diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 510ce1a7a69..9215de6d0e6 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -19,7 +19,7 @@ class MCSymbol; class MCValue; /// MCExpr - Base class for the full range of assembler expressions which are -/// needed for parsing. +/// needed for parsing. class MCExpr { public: enum ExprKind { @@ -28,18 +28,26 @@ public: SymbolRef, ///< References to labels and assigned expressions. Unary ///< Unary expressions. }; - + private: ExprKind Kind; - + + MCExpr(const MCExpr&); // DO NOT IMPLEMENT + void operator=(const MCExpr&); // DO NOT IMPLEMENT + protected: MCExpr(ExprKind _Kind) : Kind(_Kind) {} - + public: - virtual ~MCExpr(); + /// @name Accessors + /// @{ ExprKind getKind() const { return Kind; } + /// @} + /// @name Expression Evaluation + /// @{ + /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value. /// /// @param Res - The absolute value, if evaluation succeeds. @@ -53,6 +61,8 @@ public: /// @result - True on success. bool EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const; + /// @} + static bool classof(const MCExpr *) { return true; } }; @@ -60,14 +70,25 @@ public: class MCConstantExpr : public MCExpr { int64_t Value; -public: - MCConstantExpr(int64_t _Value) + MCConstantExpr(int64_t _Value) : MCExpr(MCExpr::Constant), Value(_Value) {} - + +public: + /// @name Construction + /// @{ + + static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); + + /// @} + /// @name Accessors + /// @{ + int64_t getValue() const { return Value; } - static bool classof(const MCExpr *E) { - return E->getKind() == MCExpr::Constant; + /// @} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Constant; } static bool classof(const MCConstantExpr *) { return true; } }; @@ -79,16 +100,27 @@ public: /// assembler variable (defined constant), or constitute an implicit definition /// of the symbol as external. class MCSymbolRefExpr : public MCExpr { - MCSymbol *Symbol; + const MCSymbol *Symbol; + + MCSymbolRefExpr(const MCSymbol *_Symbol) + : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {} public: - MCSymbolRefExpr(MCSymbol *_Symbol) - : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {} - - MCSymbol *getSymbol() const { return Symbol; } + /// @name Construction + /// @{ - static bool classof(const MCExpr *E) { - return E->getKind() == MCExpr::SymbolRef; + static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx); + + /// @} + /// @name Accessors + /// @{ + + const MCSymbol &getSymbol() const { return *Symbol; } + + /// @} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::SymbolRef; } static bool classof(const MCSymbolRefExpr *) { return true; } }; @@ -105,21 +137,44 @@ public: private: Opcode Op; - MCExpr *Expr; + const MCExpr *Expr; + + MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) + : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} public: - MCUnaryExpr(Opcode _Op, MCExpr *_Expr) - : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} - ~MCUnaryExpr() { - delete Expr; + /// @name Construction + /// @{ + + static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, + MCContext &Ctx); + static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { + return Create(LNot, Expr, Ctx); + } + static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { + return Create(Minus, Expr, Ctx); + } + static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { + return Create(Not, Expr, Ctx); + } + static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { + return Create(Plus, Expr, Ctx); } + /// @} + /// @name Accessors + /// @{ + + /// getOpcode - Get the kind of this unary expression. Opcode getOpcode() const { return Op; } - MCExpr *getSubExpr() const { return Expr; } + /// getSubExpr - Get the child of this unary expression. + const MCExpr *getSubExpr() const { return Expr; } - static bool classof(const MCExpr *E) { - return E->getKind() == MCExpr::Unary; + /// @} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Unary; } static bool classof(const MCUnaryExpr *) { return true; } }; @@ -150,26 +205,107 @@ public: private: Opcode Op; - MCExpr *LHS, *RHS; + const MCExpr *LHS, *RHS; + + MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) + : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} public: - MCBinaryExpr(Opcode _Op, MCExpr *_LHS, MCExpr *_RHS) - : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} - ~MCBinaryExpr() { - delete LHS; - delete RHS; + /// @name Construction + /// @{ + + static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, + const MCExpr *RHS, MCContext &Ctx); + static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Add, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(And, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Div, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(EQ, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(GT, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(GTE, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(LAnd, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(LOr, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(LT, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(LTE, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Mod, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Mul, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(NE, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Or, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Shl, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Shr, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Sub, LHS, RHS, Ctx); + } + static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, + MCContext &Ctx) { + return Create(Xor, LHS, RHS, Ctx); } + /// @} + /// @name Accessors + /// @{ + + /// getOpcode - Get the kind of this binary expression. Opcode getOpcode() const { return Op; } /// getLHS - Get the left-hand side expression of the binary operator. - MCExpr *getLHS() const { return LHS; } + const MCExpr *getLHS() const { return LHS; } /// getRHS - Get the right-hand side expression of the binary operator. - MCExpr *getRHS() const { return RHS; } + const MCExpr *getRHS() const { return RHS; } - static bool classof(const MCExpr *E) { - return E->getKind() == MCExpr::Binary; + /// @} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Binary; } static bool classof(const MCBinaryExpr *) { return true; } }; diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 91ef7e77ec8..10759687b2f 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -13,9 +13,30 @@ #include "llvm/MC/MCValue.h" using namespace llvm; -MCExpr::~MCExpr() { +const MCBinaryExpr * MCBinaryExpr::Create(Opcode Opc, + const MCExpr *LHS, + const MCExpr *RHS, + MCContext &Ctx) { + return new (Ctx) MCBinaryExpr(Opc, LHS, RHS); } +const MCUnaryExpr * MCUnaryExpr::Create(Opcode Opc, + const MCExpr *Expr, + MCContext &Ctx) { + return new (Ctx) MCUnaryExpr(Opc, Expr); +} + +const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) { + return new (Ctx) MCConstantExpr(Value); +} + +const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym, + MCContext &Ctx) { + return new (Ctx) MCSymbolRefExpr(Sym); +} + +/* *** */ + bool MCExpr::EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const { MCValue Value; @@ -50,19 +71,16 @@ static bool EvaluateSymbolicAdd(const MCValue &LHS, const MCSymbol *RHS_A, bool MCExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const { switch (getKind()) { - default: - assert(0 && "Invalid assembly expression kind!"); - case Constant: Res = MCValue::get(cast(this)->getValue()); return true; case SymbolRef: { - MCSymbol *Sym = cast(this)->getSymbol(); - if (const MCValue *Value = Ctx.GetSymbolValue(Sym)) + const MCSymbol &Sym = cast(this)->getSymbol(); + if (const MCValue *Value = Ctx.GetSymbolValue(&Sym)) Res = *Value; else - Res = MCValue::get(Sym, 0, 0); + Res = MCValue::get(&Sym, 0, 0); return true; } @@ -158,5 +176,7 @@ bool MCExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const { return true; } } -} + assert(0 && "Invalid assembly expression kind!"); + return false; +} diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index cb69bb14d06..6f002e1cb38 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -173,7 +173,7 @@ void AsmParser::EatToEndOfStatement() { /// /// parenexpr ::= expr) /// -bool AsmParser::ParseParenExpr(MCExpr *&Res) { +bool AsmParser::ParseParenExpr(const MCExpr *&Res) { if (ParseExpression(Res)) return true; if (Lexer.isNot(AsmToken::RParen)) return TokError("expected ')' in parentheses expression"); @@ -197,7 +197,7 @@ MCSymbol *AsmParser::CreateSymbol(StringRef Name) { /// primaryexpr ::= symbol /// primaryexpr ::= number /// primaryexpr ::= ~,+,- primaryexpr -bool AsmParser::ParsePrimaryExpr(MCExpr *&Res) { +bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) { switch (Lexer.getKind()) { default: return TokError("unknown token in expression"); @@ -205,7 +205,7 @@ bool AsmParser::ParsePrimaryExpr(MCExpr *&Res) { Lexer.Lex(); // Eat the operator. if (ParsePrimaryExpr(Res)) return true; - Res = new MCUnaryExpr(MCUnaryExpr::LNot, Res); + Res = MCUnaryExpr::CreateLNot(Res, Ctx); return false; case AsmToken::String: case AsmToken::Identifier: { @@ -213,12 +213,12 @@ bool AsmParser::ParsePrimaryExpr(MCExpr *&Res) { // handle things like LFOO+4. MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier()); - Res = new MCSymbolRefExpr(Sym); + Res = MCSymbolRefExpr::Create(Sym, Ctx); Lexer.Lex(); // Eat identifier. return false; } case AsmToken::Integer: - Res = new MCConstantExpr(Lexer.getTok().getIntVal()); + Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), Ctx); Lexer.Lex(); // Eat token. return false; case AsmToken::LParen: @@ -228,19 +228,19 @@ bool AsmParser::ParsePrimaryExpr(MCExpr *&Res) { Lexer.Lex(); // Eat the operator. if (ParsePrimaryExpr(Res)) return true; - Res = new MCUnaryExpr(MCUnaryExpr::Minus, Res); + Res = MCUnaryExpr::CreateMinus(Res, Ctx); return false; case AsmToken::Plus: Lexer.Lex(); // Eat the operator. if (ParsePrimaryExpr(Res)) return true; - Res = new MCUnaryExpr(MCUnaryExpr::Plus, Res); + Res = MCUnaryExpr::CreatePlus(Res, Ctx); return false; case AsmToken::Tilde: Lexer.Lex(); // Eat the operator. if (ParsePrimaryExpr(Res)) return true; - Res = new MCUnaryExpr(MCUnaryExpr::Not, Res); + Res = MCUnaryExpr::CreateNot(Res, Ctx); return false; } } @@ -252,14 +252,14 @@ bool AsmParser::ParsePrimaryExpr(MCExpr *&Res) { /// expr ::= expr *,/,%,<<,>> expr -> highest. /// expr ::= primaryexpr /// -bool AsmParser::ParseExpression(MCExpr *&Res) { +bool AsmParser::ParseExpression(const MCExpr *&Res) { Res = 0; return ParsePrimaryExpr(Res) || ParseBinOpRHS(1, Res); } bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { - MCExpr *Expr; + const MCExpr *Expr; SMLoc StartLoc = Lexer.getLoc(); if (ParseExpression(Expr)) @@ -272,7 +272,7 @@ bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { } bool AsmParser::ParseRelocatableExpression(MCValue &Res) { - MCExpr *Expr; + const MCExpr *Expr; SMLoc StartLoc = Lexer.getLoc(); if (ParseExpression(Expr)) @@ -285,7 +285,7 @@ bool AsmParser::ParseRelocatableExpression(MCValue &Res) { } bool AsmParser::ParseParenRelocatableExpression(MCValue &Res) { - MCExpr *Expr; + const MCExpr *Expr; SMLoc StartLoc = Lexer.getLoc(); if (ParseParenExpr(Expr)) @@ -372,7 +372,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. /// Res contains the LHS of the expression on input. -bool AsmParser::ParseBinOpRHS(unsigned Precedence, MCExpr *&Res) { +bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) { while (1) { MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); @@ -385,7 +385,7 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, MCExpr *&Res) { Lexer.Lex(); // Eat the next primary expression. - MCExpr *RHS; + const MCExpr *RHS; if (ParsePrimaryExpr(RHS)) return true; // If BinOp binds less tightly with RHS than the operator after RHS, let @@ -397,7 +397,7 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, MCExpr *&Res) { } // Merge LHS and RHS according to operator. - Res = new MCBinaryExpr(Kind, Res, RHS); + Res = MCBinaryExpr::Create(Kind, Res, RHS, Ctx); } } diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index 99e5bbede55..c7b7316d632 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -66,7 +66,7 @@ public: virtual bool Error(SMLoc L, const Twine &Msg); - virtual bool ParseExpression(MCExpr *&Res); + virtual bool ParseExpression(const MCExpr *&Res); virtual bool ParseAbsoluteExpression(int64_t &Res); @@ -104,9 +104,9 @@ private: /// @see ParseRelocatableExpression, ParseParenExpr. bool ParseParenRelocatableExpression(MCValue &Res); - bool ParsePrimaryExpr(MCExpr *&Res); - bool ParseBinOpRHS(unsigned Precedence, MCExpr *&Res); - bool ParseParenExpr(MCExpr *&Res); + bool ParsePrimaryExpr(const MCExpr *&Res); + bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res); + bool ParseParenExpr(const MCExpr *&Res); /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) /// and set \arg Res to the identifier contents.