forked from OSchip/llvm-project
Add AST nodes and actions for paren exprs and simple unary ops.
llvm-svn: 38940
This commit is contained in:
parent
9b6d4cb90e
commit
1b92649857
|
@ -0,0 +1,121 @@
|
|||
//===--- 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 <iostream>
|
||||
using namespace llvm;
|
||||
using namespace clang;
|
||||
|
||||
void Expr::dump() const {
|
||||
if (this == 0)
|
||||
std::cerr << "<null expr>";
|
||||
else
|
||||
dump_impl();
|
||||
}
|
||||
|
||||
|
||||
void IntegerConstant::dump_impl() const {
|
||||
std::cerr << "1";
|
||||
}
|
||||
|
||||
void FloatingConstant::dump_impl() const {
|
||||
std::cerr << "1.0";
|
||||
}
|
||||
|
||||
void ParenExpr::dump_impl() const {
|
||||
std::cerr << "'('";
|
||||
Val->dump();
|
||||
std::cerr << "')'";
|
||||
}
|
||||
|
||||
/// 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 binary operator");
|
||||
case PostInc: return "[post]++";
|
||||
case PostDec: return "[post]--";
|
||||
case PreInc: return "[pre]++";
|
||||
case PreDec: return "[pre]--";
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
void UnaryOperator::dump_impl() const {
|
||||
std::cerr << "(" << getOpcodeStr(Opc);
|
||||
Input->dump();
|
||||
std::cerr << ")";
|
||||
}
|
||||
|
||||
/// 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 ",";
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryOperator::dump_impl() const {
|
||||
std::cerr << "(";
|
||||
LHS->dump();
|
||||
std::cerr << " " << getOpcodeStr(Opc) << " ";
|
||||
RHS->dump();
|
||||
std::cerr << ")";
|
||||
}
|
||||
|
||||
void ConditionalOperator::dump_impl() const {
|
||||
std::cerr << "(";
|
||||
Cond->dump();
|
||||
std::cerr << " ? ";
|
||||
LHS->dump();
|
||||
std::cerr << " : ";
|
||||
RHS->dump();
|
||||
std::cerr << ")";
|
||||
}
|
|
@ -40,10 +40,17 @@ public:
|
|||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Parsing Callbacks.
|
||||
|
||||
// Primary Expressions.
|
||||
virtual ExprTy *ParseIntegerConstant(const LexerToken &Tok);
|
||||
virtual ExprTy *ParseFloatingConstant(const LexerToken &Tok);
|
||||
virtual ExprTy *ParseParenExpr(SourceLocation L, SourceLocation R,
|
||||
ExprTy *Val);
|
||||
|
||||
// Binary/Unary Operators. 'Tok' is the token for the operator.
|
||||
virtual ExprTy *ParseUnaryOp(const LexerToken &Tok, ExprTy *Input);
|
||||
virtual ExprTy *ParsePostfixUnaryOp(const LexerToken &Tok, ExprTy *Input);
|
||||
|
||||
// Binary Operators. 'Tok' is the token
|
||||
virtual ExprTy *ParseBinOp(const LexerToken &Tok, ExprTy *LHS, ExprTy *RHS);
|
||||
|
||||
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
|
||||
|
@ -106,6 +113,55 @@ ASTBuilder::ExprTy *ASTBuilder::ParseFloatingConstant(const LexerToken &Tok) {
|
|||
return new FloatingConstant();
|
||||
}
|
||||
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParseParenExpr(SourceLocation L,
|
||||
SourceLocation R,
|
||||
ExprTy *Val) {
|
||||
// FIXME: This is obviously just for testing.
|
||||
((Expr*)Val)->dump();
|
||||
if (!FullLocInfo) return Val;
|
||||
|
||||
return new ParenExpr(L, R, (Expr*)Val);
|
||||
}
|
||||
|
||||
// Unary Operators. 'Tok' is the token for the operator.
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParseUnaryOp(const LexerToken &Tok,
|
||||
ExprTy *Input) {
|
||||
UnaryOperator::Opcode Opc;
|
||||
switch (Tok.getKind()) {
|
||||
default: assert(0 && "Unknown unary op!");
|
||||
case tok::plusplus: Opc = UnaryOperator::PreInc; break;
|
||||
case tok::minusminus: Opc = UnaryOperator::PreDec; break;
|
||||
case tok::amp: Opc = UnaryOperator::AddrOf; break;
|
||||
case tok::star: Opc = UnaryOperator::Deref; break;
|
||||
case tok::plus: Opc = UnaryOperator::Plus; break;
|
||||
case tok::minus: Opc = UnaryOperator::Minus; break;
|
||||
case tok::tilde: Opc = UnaryOperator::Not; break;
|
||||
case tok::exclaim: Opc = UnaryOperator::LNot; break;
|
||||
case tok::kw___real: Opc = UnaryOperator::Real; break;
|
||||
case tok::kw___imag: Opc = UnaryOperator::Imag; break;
|
||||
}
|
||||
|
||||
if (!FullLocInfo)
|
||||
return new UnaryOperator((Expr*)Input, Opc);
|
||||
else
|
||||
return new UnaryOperatorLOC(Tok.getLocation(), (Expr*)Input, Opc);
|
||||
}
|
||||
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParsePostfixUnaryOp(const LexerToken &Tok,
|
||||
ExprTy *Input) {
|
||||
UnaryOperator::Opcode Opc;
|
||||
switch (Tok.getKind()) {
|
||||
default: assert(0 && "Unknown unary op!");
|
||||
case tok::plusplus: Opc = UnaryOperator::PostInc; break;
|
||||
case tok::minusminus: Opc = UnaryOperator::PostDec; break;
|
||||
}
|
||||
|
||||
if (!FullLocInfo)
|
||||
return new UnaryOperator((Expr*)Input, Opc);
|
||||
else
|
||||
return new UnaryOperatorLOC(Tok.getLocation(), (Expr*)Input, Opc);
|
||||
}
|
||||
|
||||
// Binary Operators. 'Tok' is the token for the operator.
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParseBinOp(const LexerToken &Tok, ExprTy *LHS,
|
||||
ExprTy *RHS) {
|
||||
|
|
|
@ -416,6 +416,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
|
|||
///
|
||||
Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
||||
ExprResult Res;
|
||||
LexerToken SavedTok;
|
||||
|
||||
// This handles all of cast-expression, unary-expression, postfix-expression,
|
||||
// and primary-expression. We handle them together like this for efficiency
|
||||
|
@ -491,8 +492,12 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
|||
return ParseBuiltinPrimaryExpression();
|
||||
case tok::plusplus: // unary-expression: '++' unary-expression
|
||||
case tok::minusminus: // unary-expression: '--' unary-expression
|
||||
SavedTok = Tok;
|
||||
ConsumeToken();
|
||||
return ParseCastExpression(true);
|
||||
Res = ParseCastExpression(true);
|
||||
if (!Res.isInvalid)
|
||||
Res = Actions.ParseUnaryOp(SavedTok, Res.Val);
|
||||
return Res;
|
||||
case tok::amp: // unary-expression: '&' cast-expression
|
||||
case tok::star: // unary-expression: '*' cast-expression
|
||||
case tok::plus: // unary-expression: '+' cast-expression
|
||||
|
@ -500,10 +505,14 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
|||
case tok::tilde: // unary-expression: '~' cast-expression
|
||||
case tok::exclaim: // unary-expression: '!' cast-expression
|
||||
case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
|
||||
case tok::kw___imag: // unary-expression: '__real' cast-expression [GNU]
|
||||
case tok::kw___imag: // unary-expression: '__imag' cast-expression [GNU]
|
||||
//case tok::kw__extension__: [TODO]
|
||||
SavedTok = Tok;
|
||||
ConsumeToken();
|
||||
return ParseCastExpression(false);
|
||||
Res = ParseCastExpression(false);
|
||||
if (!Res.isInvalid)
|
||||
Res = Actions.ParseUnaryOp(SavedTok, Res.Val);
|
||||
return Res;
|
||||
|
||||
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
|
||||
// unary-expression: 'sizeof' '(' type-name ')'
|
||||
|
@ -594,6 +603,8 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
|||
|
||||
case tok::plusplus: // postfix-expression: postfix-expression '++'
|
||||
case tok::minusminus: // postfix-expression: postfix-expression '--'
|
||||
if (!LHS.isInvalid)
|
||||
LHS = Actions.ParsePostfixUnaryOp(Tok, LHS.Val);
|
||||
ConsumeToken();
|
||||
break;
|
||||
}
|
||||
|
@ -749,6 +760,7 @@ Parser::ExprResult Parser::ParseStringLiteralExpression() {
|
|||
// considered to be strings.
|
||||
while (isTokenStringLiteral())
|
||||
ConsumeStringToken();
|
||||
// TODO: Build AST for string literals.
|
||||
return ExprResult(false);
|
||||
}
|
||||
|
||||
|
@ -777,6 +789,7 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
|
|||
Diag(Tok, diag::ext_gnu_statement_expr);
|
||||
ParseCompoundStatement();
|
||||
ExprType = CompoundStmt;
|
||||
// TODO: Build AST for GNU compound stmt.
|
||||
} else if (ExprType >= CompoundLiteral && isTypeSpecifierQualifier()) {
|
||||
// Otherwise, this is a compound literal expression or cast expression.
|
||||
ParseTypeName();
|
||||
|
@ -789,9 +802,11 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
|
|||
Diag(OpenLoc, diag::ext_c99_compound_literal);
|
||||
Result = ParseInitializer();
|
||||
ExprType = CompoundLiteral;
|
||||
// TODO: Build AST for compound literal.
|
||||
} else if (ExprType == CastExpr) {
|
||||
// Note that this doesn't parse the subsequence cast-expression.
|
||||
ExprType = CastExpr;
|
||||
// TODO: Build AST for cast in caller.
|
||||
} else {
|
||||
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
|
||||
return ExprResult(true);
|
||||
|
@ -800,6 +815,8 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
|
|||
} else {
|
||||
Result = ParseExpression();
|
||||
ExprType = SimpleExpr;
|
||||
if (!Result.isInvalid && Tok.getKind() == tok::r_paren)
|
||||
Result = Actions.ParseParenExpr(OpenLoc, Tok.getLocation(), Result.Val);
|
||||
}
|
||||
|
||||
// Match the ')'.
|
||||
|
@ -807,5 +824,6 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
|
|||
SkipUntil(tok::r_paren);
|
||||
else
|
||||
MatchRHSPunctuation(tok::r_paren, OpenLoc);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -40,10 +40,17 @@ public:
|
|||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Parsing Callbacks.
|
||||
|
||||
// Primary Expressions.
|
||||
virtual ExprTy *ParseIntegerConstant(const LexerToken &Tok);
|
||||
virtual ExprTy *ParseFloatingConstant(const LexerToken &Tok);
|
||||
virtual ExprTy *ParseParenExpr(SourceLocation L, SourceLocation R,
|
||||
ExprTy *Val);
|
||||
|
||||
// Binary/Unary Operators. 'Tok' is the token for the operator.
|
||||
virtual ExprTy *ParseUnaryOp(const LexerToken &Tok, ExprTy *Input);
|
||||
virtual ExprTy *ParsePostfixUnaryOp(const LexerToken &Tok, ExprTy *Input);
|
||||
|
||||
// Binary Operators. 'Tok' is the token
|
||||
virtual ExprTy *ParseBinOp(const LexerToken &Tok, ExprTy *LHS, ExprTy *RHS);
|
||||
|
||||
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
|
||||
|
@ -106,6 +113,55 @@ ASTBuilder::ExprTy *ASTBuilder::ParseFloatingConstant(const LexerToken &Tok) {
|
|||
return new FloatingConstant();
|
||||
}
|
||||
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParseParenExpr(SourceLocation L,
|
||||
SourceLocation R,
|
||||
ExprTy *Val) {
|
||||
// FIXME: This is obviously just for testing.
|
||||
((Expr*)Val)->dump();
|
||||
if (!FullLocInfo) return Val;
|
||||
|
||||
return new ParenExpr(L, R, (Expr*)Val);
|
||||
}
|
||||
|
||||
// Unary Operators. 'Tok' is the token for the operator.
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParseUnaryOp(const LexerToken &Tok,
|
||||
ExprTy *Input) {
|
||||
UnaryOperator::Opcode Opc;
|
||||
switch (Tok.getKind()) {
|
||||
default: assert(0 && "Unknown unary op!");
|
||||
case tok::plusplus: Opc = UnaryOperator::PreInc; break;
|
||||
case tok::minusminus: Opc = UnaryOperator::PreDec; break;
|
||||
case tok::amp: Opc = UnaryOperator::AddrOf; break;
|
||||
case tok::star: Opc = UnaryOperator::Deref; break;
|
||||
case tok::plus: Opc = UnaryOperator::Plus; break;
|
||||
case tok::minus: Opc = UnaryOperator::Minus; break;
|
||||
case tok::tilde: Opc = UnaryOperator::Not; break;
|
||||
case tok::exclaim: Opc = UnaryOperator::LNot; break;
|
||||
case tok::kw___real: Opc = UnaryOperator::Real; break;
|
||||
case tok::kw___imag: Opc = UnaryOperator::Imag; break;
|
||||
}
|
||||
|
||||
if (!FullLocInfo)
|
||||
return new UnaryOperator((Expr*)Input, Opc);
|
||||
else
|
||||
return new UnaryOperatorLOC(Tok.getLocation(), (Expr*)Input, Opc);
|
||||
}
|
||||
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParsePostfixUnaryOp(const LexerToken &Tok,
|
||||
ExprTy *Input) {
|
||||
UnaryOperator::Opcode Opc;
|
||||
switch (Tok.getKind()) {
|
||||
default: assert(0 && "Unknown unary op!");
|
||||
case tok::plusplus: Opc = UnaryOperator::PostInc; break;
|
||||
case tok::minusminus: Opc = UnaryOperator::PostDec; break;
|
||||
}
|
||||
|
||||
if (!FullLocInfo)
|
||||
return new UnaryOperator((Expr*)Input, Opc);
|
||||
else
|
||||
return new UnaryOperatorLOC(Tok.getLocation(), (Expr*)Input, Opc);
|
||||
}
|
||||
|
||||
// Binary Operators. 'Tok' is the token for the operator.
|
||||
ASTBuilder::ExprTy *ASTBuilder::ParseBinOp(const LexerToken &Tok, ExprTy *LHS,
|
||||
ExprTy *RHS) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06E8130A8FF9330050E87E /* Action.h */; };
|
||||
DE0FCA210A95710600248FD5 /* EmptyAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0FCA200A95710600248FD5 /* EmptyAction.cpp */; };
|
||||
DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE0FCA620A95859D00248FD5 /* Expr.h */; };
|
||||
DE0FCB340A9C21F100248FD5 /* Expr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0FCB330A9C21F100248FD5 /* Expr.cpp */; };
|
||||
DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
|
||||
DE1F24820A7DCD3800FBF588 /* Declarations.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F24810A7DCD3800FBF588 /* Declarations.h */; };
|
||||
DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */; };
|
||||
|
@ -119,6 +120,7 @@
|
|||
DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = "<group>"; };
|
||||
DE0FCA200A95710600248FD5 /* EmptyAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = EmptyAction.cpp; path = Parse/EmptyAction.cpp; sourceTree = "<group>"; };
|
||||
DE0FCA620A95859D00248FD5 /* Expr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Expr.h; path = clang/AST/Expr.h; sourceTree = "<group>"; };
|
||||
DE0FCB330A9C21F100248FD5 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Expr.cpp; path = AST/Expr.cpp; sourceTree = "<group>"; };
|
||||
DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; };
|
||||
DE1F24810A7DCD3800FBF588 /* Declarations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Declarations.h; path = clang/Parse/Declarations.h; sourceTree = "<group>"; };
|
||||
DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = "<group>"; };
|
||||
|
@ -268,6 +270,7 @@
|
|||
children = (
|
||||
DEC8DAAC0A94400300353FCA /* ASTStreamer.cpp */,
|
||||
DEC8D9B50A9434FA00353FCA /* Builder.cpp */,
|
||||
DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
|
||||
);
|
||||
name = AST;
|
||||
sourceTree = "<group>";
|
||||
|
@ -411,6 +414,7 @@
|
|||
DEC8DA1E0A94388B00353FCA /* PrintParserCallbacks.cpp in Sources */,
|
||||
DEC8DAAD0A94400300353FCA /* ASTStreamer.cpp in Sources */,
|
||||
DE0FCA210A95710600248FD5 /* EmptyAction.cpp in Sources */,
|
||||
DE0FCB340A9C21F100248FD5 /* Expr.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -26,16 +26,75 @@ class Expr {
|
|||
public:
|
||||
Expr() {}
|
||||
virtual ~Expr() {}
|
||||
|
||||
// FIXME: Change to non-virtual method that uses visitor pattern to do this.
|
||||
void dump() const;
|
||||
|
||||
private:
|
||||
virtual void dump_impl() const = 0;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Primary Expressions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class IntegerConstant : public Expr {
|
||||
public:
|
||||
IntegerConstant() {}
|
||||
virtual void dump_impl() const;
|
||||
};
|
||||
|
||||
class FloatingConstant : public Expr {
|
||||
public:
|
||||
FloatingConstant() {}
|
||||
virtual void dump_impl() const;
|
||||
};
|
||||
|
||||
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
|
||||
/// AST node is only formed if full location information is requested.
|
||||
class ParenExpr : public Expr {
|
||||
SourceLocation L, R;
|
||||
Expr *Val;
|
||||
public:
|
||||
ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
|
||||
: L(l), R(r), Val(val) {}
|
||||
virtual void dump_impl() const;
|
||||
};
|
||||
|
||||
|
||||
/// UnaryOperator - This represents the unary-expression's (except sizeof), the
|
||||
/// postinc/postdec operators from postfix-expression, and various extensions.
|
||||
class UnaryOperator : public Expr {
|
||||
public:
|
||||
enum Opcode {
|
||||
PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators
|
||||
PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators.
|
||||
AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators.
|
||||
Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators.
|
||||
Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators.
|
||||
Real, Imag // "__real expr"/"__imag expr" Extension.
|
||||
};
|
||||
|
||||
UnaryOperator(Expr *input, Opcode opc)
|
||||
: Input(input), Opc(opc) {}
|
||||
|
||||
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
||||
/// corresponds to, e.g. "sizeof" or "[pre]++"
|
||||
static const char *getOpcodeStr(Opcode Op);
|
||||
|
||||
virtual void dump_impl() const;
|
||||
|
||||
private:
|
||||
Expr *Input;
|
||||
Opcode Opc;
|
||||
};
|
||||
|
||||
class UnaryOperatorLOC : public UnaryOperator {
|
||||
SourceLocation Loc;
|
||||
public:
|
||||
UnaryOperatorLOC(SourceLocation loc, Expr *Input, Opcode Opc)
|
||||
: UnaryOperator(Input, Opc), Loc(loc) {}
|
||||
|
||||
};
|
||||
|
||||
class BinaryOperator : public Expr {
|
||||
|
@ -64,6 +123,12 @@ public:
|
|||
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc)
|
||||
: LHS(lhs), RHS(rhs), Opc(opc) {}
|
||||
|
||||
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
||||
/// corresponds to, e.g. "<<=".
|
||||
static const char *getOpcodeStr(Opcode Op);
|
||||
|
||||
virtual void dump_impl() const;
|
||||
|
||||
private:
|
||||
Expr *LHS, *RHS;
|
||||
Opcode Opc;
|
||||
|
@ -85,6 +150,7 @@ class ConditionalOperator : public Expr {
|
|||
public:
|
||||
ConditionalOperator(Expr *cond, Expr *lhs, Expr *rhs)
|
||||
: Cond(cond), LHS(lhs), RHS(rhs) {}
|
||||
virtual void dump_impl() const;
|
||||
};
|
||||
|
||||
/// ConditionalOperatorLOC - ConditionalOperator with full location info.
|
||||
|
|
|
@ -73,8 +73,19 @@ public:
|
|||
// Primary Expressions.
|
||||
virtual ExprTy *ParseIntegerConstant(const LexerToken &Tok) { return 0; }
|
||||
virtual ExprTy *ParseFloatingConstant(const LexerToken &Tok) { return 0; }
|
||||
|
||||
// Binary Operators. 'Tok' is the token
|
||||
|
||||
virtual ExprTy *ParseParenExpr(SourceLocation L, SourceLocation R,
|
||||
ExprTy *Val) {
|
||||
return Val;
|
||||
}
|
||||
|
||||
// Binary/Unary Operators. 'Tok' is the token for the operator.
|
||||
virtual ExprTy *ParseUnaryOp(const LexerToken &Tok, ExprTy *Input) {
|
||||
return 0;
|
||||
}
|
||||
virtual ExprTy *ParsePostfixUnaryOp(const LexerToken &Tok, ExprTy *Input) {
|
||||
return 0;
|
||||
}
|
||||
virtual ExprTy *ParseBinOp(const LexerToken &Tok, ExprTy *LHS, ExprTy *RHS) {
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue