From 1c20a170c03dadf2129d5c380bc339931944b74f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 26 Aug 2007 03:42:43 +0000 Subject: [PATCH] add a new ImaginaryLiteral AST node that is used to represent imaginary literals: float _Complex A; void foo() { A = 1.0iF; } generates: (BinaryOperator 0x2305ec0 '_Complex float' '=' (DeclRefExpr 0x2305e60 '_Complex float' Decl='A' 0x2305cf0) (ImaginaryLiteral 0x2305f40 '_Complex float' (FloatingLiteral 0x2305ea0 'float' 1.000000)))) llvm-svn: 41413 --- clang/AST/Expr.cpp | 56 +++++++++++---------------- clang/AST/StmtDumper.cpp | 8 ++++ clang/AST/StmtPrinter.cpp | 6 +++ clang/Sema/SemaExpr.cpp | 23 +++++++---- clang/clang.xcodeproj/project.pbxproj | 2 +- clang/include/clang/AST/Expr.h | 27 ++++++++++++- clang/include/clang/AST/StmtNodes.def | 31 ++++++++------- 7 files changed, 96 insertions(+), 57 deletions(-) diff --git a/clang/AST/Expr.cpp b/clang/AST/Expr.cpp index 535e1ef786f1..0f6ac7492b7f 100644 --- a/clang/AST/Expr.cpp +++ b/clang/AST/Expr.cpp @@ -738,6 +738,14 @@ Stmt::child_iterator CharacterLiteral::child_end() { return NULL; } Stmt::child_iterator FloatingLiteral::child_begin() { return NULL; } Stmt::child_iterator FloatingLiteral::child_end() { return NULL; } +// ImaginaryLiteral +Stmt::child_iterator ImaginaryLiteral::child_begin() { + return reinterpret_cast(&Val); +} +Stmt::child_iterator ImaginaryLiteral::child_end() { + return reinterpret_cast(&Val)+1; +} + // StringLiteral Stmt::child_iterator StringLiteral::child_begin() { return NULL; } Stmt::child_iterator StringLiteral::child_end() { return NULL; } @@ -746,122 +754,104 @@ Stmt::child_iterator StringLiteral::child_end() { return NULL; } Stmt::child_iterator ParenExpr::child_begin() { return reinterpret_cast(&Val); } - Stmt::child_iterator ParenExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&Val)+1; } // UnaryOperator Stmt::child_iterator UnaryOperator::child_begin() { return reinterpret_cast(&Val); } - Stmt::child_iterator UnaryOperator::child_end() { - return child_begin()+1; + return reinterpret_cast(&Val)+1; } // SizeOfAlignOfTypeExpr -Stmt::child_iterator SizeOfAlignOfTypeExpr::child_begin() { - return NULL; -} - -Stmt::child_iterator SizeOfAlignOfTypeExpr::child_end() { - return NULL; -} +Stmt::child_iterator SizeOfAlignOfTypeExpr::child_begin() { return NULL; } +Stmt::child_iterator SizeOfAlignOfTypeExpr::child_end() { return NULL; } // ArraySubscriptExpr Stmt::child_iterator ArraySubscriptExpr::child_begin() { return reinterpret_cast(&SubExprs); } - Stmt::child_iterator ArraySubscriptExpr::child_end() { - return child_begin()+END_EXPR; + return reinterpret_cast(&SubExprs)+END_EXPR; } // CallExpr Stmt::child_iterator CallExpr::child_begin() { return reinterpret_cast(&SubExprs); } - Stmt::child_iterator CallExpr::child_end() { - return child_begin()+NumArgs+ARGS_START; + return reinterpret_cast(&SubExprs)+NumArgs+ARGS_START; } // MemberExpr Stmt::child_iterator MemberExpr::child_begin() { return reinterpret_cast(&Base); } - Stmt::child_iterator MemberExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&Base)+1; } // OCUVectorElementExpr Stmt::child_iterator OCUVectorElementExpr::child_begin() { return reinterpret_cast(&Base); } - Stmt::child_iterator OCUVectorElementExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&Base)+1; } // CompoundLiteralExpr Stmt::child_iterator CompoundLiteralExpr::child_begin() { return reinterpret_cast(&Init); } - Stmt::child_iterator CompoundLiteralExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&Init)+1; } // ImplicitCastExpr Stmt::child_iterator ImplicitCastExpr::child_begin() { return reinterpret_cast(&Op); } - Stmt::child_iterator ImplicitCastExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&Op)+1; } // CastExpr Stmt::child_iterator CastExpr::child_begin() { return reinterpret_cast(&Op); } - Stmt::child_iterator CastExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&Op)+1; } // BinaryOperator Stmt::child_iterator BinaryOperator::child_begin() { return reinterpret_cast(&SubExprs); } - Stmt::child_iterator BinaryOperator::child_end() { - return child_begin()+END_EXPR; + return reinterpret_cast(&SubExprs)+END_EXPR; } // ConditionalOperator Stmt::child_iterator ConditionalOperator::child_begin() { return reinterpret_cast(&SubExprs); } - Stmt::child_iterator ConditionalOperator::child_end() { - return child_begin()+END_EXPR; + return reinterpret_cast(&SubExprs)+END_EXPR; } // AddrLabelExpr Stmt::child_iterator AddrLabelExpr::child_begin() { return NULL; } Stmt::child_iterator AddrLabelExpr::child_end() { return NULL; } - // StmtExpr Stmt::child_iterator StmtExpr::child_begin() { return reinterpret_cast(&SubStmt); } - Stmt::child_iterator StmtExpr::child_end() { - return child_begin()+1; + return reinterpret_cast(&SubStmt)+1; } // TypesCompatibleExpr @@ -874,7 +864,7 @@ Stmt::child_iterator ChooseExpr::child_begin() { } Stmt::child_iterator ChooseExpr::child_end() { - return child_begin()+END_EXPR; + return reinterpret_cast(&SubExprs)+END_EXPR; } // ObjCStringLiteral diff --git a/clang/AST/StmtDumper.cpp b/clang/AST/StmtDumper.cpp index 0a46cbc5c125..0ac7a19ddadd 100644 --- a/clang/AST/StmtDumper.cpp +++ b/clang/AST/StmtDumper.cpp @@ -328,6 +328,14 @@ void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) { DumpExpr(Node); fprintf(F, " %f)", Node->getValue()); } + +void StmtDumper::VisitImaginaryLiteral(ImaginaryLiteral *Node) { + DumpExpr(Node); + fprintf(F, "\n"); + DumpSubTree(Node->getSubExpr()); + fprintf(F, ")"); +} + void StmtDumper::VisitStringLiteral(StringLiteral *Str) { DumpExpr(Str); // FIXME: this doesn't print wstrings right. diff --git a/clang/AST/StmtPrinter.cpp b/clang/AST/StmtPrinter.cpp index 633278f2fd69..875af790201a 100644 --- a/clang/AST/StmtPrinter.cpp +++ b/clang/AST/StmtPrinter.cpp @@ -379,6 +379,12 @@ void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { // FIXME: print value more precisely. OS << Node->getValue(); } + +void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { + PrintExpr(Node->getSubExpr()); + OS << "i"; +} + void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { if (Str->isWide()) OS << 'L'; OS << '"'; diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 1c539558f845..e4dd9bb490f2 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -141,7 +141,15 @@ Action::ExprResult Sema::ParseNumericConstant(const Token &Tok) { if (Literal.hadError) return ExprResult(true); - if (Literal.isIntegerLiteral()) { + Expr *Res; + + if (Literal.isFloatingLiteral()) { + // FIXME: handle float values > 32 (including compute the real type...). + QualType Ty = Literal.isFloat ? Context.FloatTy : Context.DoubleTy; + Res = new FloatingLiteral(Literal.GetFloatValue(), Ty, Tok.getLocation()); + } else if (!Literal.isIntegerLiteral()) { + return ExprResult(true); + } else { QualType t; // Get the value in the widest-possible width. @@ -218,13 +226,14 @@ Action::ExprResult Sema::ParseNumericConstant(const Token &Tok) { } } - return new IntegerLiteral(ResultVal, t, Tok.getLocation()); - } else if (Literal.isFloatingLiteral()) { - // FIXME: handle float values > 32 (including compute the real type...). - QualType Ty = Literal.isFloat ? Context.FloatTy : Context.DoubleTy; - return new FloatingLiteral(Literal.GetFloatValue(), Ty, Tok.getLocation()); + Res = new IntegerLiteral(ResultVal, t, Tok.getLocation()); } - return ExprResult(true); + + // If this is an imaginary literal, create the ImaginaryLiteral wrapper. + if (Literal.isImaginary) + Res = new ImaginaryLiteral(Res, Context.getComplexType(Res->getType())); + + return Res; } Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R, diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index cb6a73d08b14..d86dfbb0eeff 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -210,7 +210,7 @@ 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = AST/ExprCXX.cpp; sourceTree = ""; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = ""; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; }; - 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = ""; }; DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = ""; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = ""; }; diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index e571f11792c6..8a4f6affbbc7 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -216,7 +216,7 @@ public: }; class FloatingLiteral : public Expr { - float Value; // FIXME + float Value; // FIXME: Change to APFloat SourceLocation Loc; public: FloatingLiteral(float value, QualType type, SourceLocation l) @@ -236,6 +236,31 @@ public: virtual child_iterator child_end(); }; +/// ImaginaryLiteral - We support imaginary integer and floating point literals, +/// like "1.0i". We represent these as a wrapper around FloatingLiteral and +/// IntegerLiteral classes. Instances of this class always have a Complex type +/// whose element type matches the subexpression. +/// +class ImaginaryLiteral : public Expr { + Expr *Val; +public: + ImaginaryLiteral(Expr *val, QualType Ty) + : Expr(ImaginaryLiteralClass, Ty), Val(val) {} + + const Expr *getSubExpr() const { return Val; } + Expr *getSubExpr() { return Val; } + + virtual SourceRange getSourceRange() const { return Val->getSourceRange(); } + static bool classof(const Stmt *T) { + return T->getStmtClass() == ImaginaryLiteralClass; + } + static bool classof(const ImaginaryLiteral *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + /// StringLiteral - This represents a string literal expression, e.g. "foo" /// or L"bar" (wide strings). The actual string is returned by getStrData() /// is NOT null-terminated, and the length of the string is determined by diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index 6d23a6777641..bc022775a02e 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -49,21 +49,22 @@ STMT(32, PreDefinedExpr , Expr) STMT(33, DeclRefExpr , Expr) STMT(34, IntegerLiteral , Expr) STMT(35, FloatingLiteral , Expr) -STMT(36, StringLiteral , Expr) -STMT(37, CharacterLiteral , Expr) -STMT(38, ParenExpr , Expr) -STMT(39, UnaryOperator , Expr) -STMT(40, SizeOfAlignOfTypeExpr , Expr) -STMT(41, ArraySubscriptExpr , Expr) -STMT(42, CallExpr , Expr) -STMT(43, MemberExpr , Expr) -STMT(44, CastExpr , Expr) -STMT(45, BinaryOperator , Expr) -STMT(46, CompoundAssignOperator, BinaryOperator) -STMT(47, ConditionalOperator , Expr) -STMT(48, ImplicitCastExpr , Expr) -STMT(49, CompoundLiteralExpr , Expr) -STMT(50, OCUVectorElementExpr , Expr) +STMT(36, ImaginaryLiteral , Expr) +STMT(37, StringLiteral , Expr) +STMT(38, CharacterLiteral , Expr) +STMT(39, ParenExpr , Expr) +STMT(40, UnaryOperator , Expr) +STMT(41, SizeOfAlignOfTypeExpr , Expr) +STMT(42, ArraySubscriptExpr , Expr) +STMT(43, CallExpr , Expr) +STMT(44, MemberExpr , Expr) +STMT(45, CastExpr , Expr) +STMT(46, BinaryOperator , Expr) +STMT(47, CompoundAssignOperator, BinaryOperator) +STMT(48, ConditionalOperator , Expr) +STMT(49, ImplicitCastExpr , Expr) +STMT(50, CompoundLiteralExpr , Expr) +STMT(51, OCUVectorElementExpr , Expr) // GNU Extensions. STMT(55, AddrLabelExpr , Expr)