diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-07 08:35:16 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-07 08:35:16 +0000 |
commit | 9fcce65e7e1307b5b8da9be13e4092d6bb94dc1d (patch) | |
tree | 2442cd0ff555a2ecf676e6f35d4df696831406d1 /include/clang | |
parent | b65e24a690482e239dbd7f292bed3e87f644f8f7 (diff) |
AST representation for user-defined literals, plus just enough of semantic
analysis to make the AST representation testable. They are represented by a
new UserDefinedLiteral AST node, which is a sugared CallExpr. All semantic
properties, including full CodeGen support, are achieved for free by this
representation.
UserDefinedLiterals can never be dependent, so no custom instantiation
behavior is required. They are mangled as if they were direct calls to the
underlying literal operator. This matches g++'s apparent behavior (but not its
actual mangling, which is broken for literal-operator-ids).
User-defined *string* literals are now fully-operational, but the semantic
analysis is quite hacky and needs more work. No other forms of user-defined
literal are created yet, but the AST support for them is present.
This patch committed after midnight because we had already hit the quota for
new kinds of literal yesterday.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152211 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/ExprCXX.h | 61 | ||||
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 1 | ||||
-rw-r--r-- | include/clang/Basic/StmtNodes.td | 1 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 2 |
5 files changed, 70 insertions, 0 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 9631f54975..a9699f1ce8 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -324,6 +324,67 @@ public: static bool classof(const CXXConstCastExpr *) { return true; } }; +/// UserDefinedLiteral - A call to a literal operator (C++11 [over.literal]) +/// written as a user-defined literal (C++11 [lit.ext]). +/// +/// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this +/// is semantically equivalent to a normal call, this AST node provides better +/// information about the syntactic representation of the literal. +/// +/// Since literal operators are never found by ADL and can only be declared at +/// namespace scope, a user-defined literal is never dependent. +class UserDefinedLiteral : public CallExpr { + /// \brief The location of a ud-suffix within the literal. + SourceLocation UDSuffixLoc; + +public: + UserDefinedLiteral(ASTContext &C, Expr *Fn, Expr **Args, unsigned NumArgs, + QualType T, ExprValueKind VK, SourceLocation LitEndLoc, + SourceLocation SuffixLoc) + : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, NumArgs, T, VK, + LitEndLoc), UDSuffixLoc(SuffixLoc) {} + explicit UserDefinedLiteral(ASTContext &C, EmptyShell Empty) + : CallExpr(C, UserDefinedLiteralClass, Empty) {} + + /// The kind of literal operator which is invoked. + enum LiteralOperatorKind { + LOK_Raw, ///< Raw form: operator "" X (const char *) + LOK_Template, ///< Raw form: operator "" X<cs...> () + LOK_Integer, ///< operator "" X (unsigned long long) + LOK_Floating, ///< operator "" X (long double) + LOK_String, ///< operator "" X (const CharT *, size_t) + LOK_Character ///< operator "" X (CharT) + }; + + /// getLiteralOperatorKind - Returns the kind of literal operator invocation + /// which this expression represents. + LiteralOperatorKind getLiteralOperatorKind() const; + + /// getCookedLiteral - If this is not a raw user-defined literal, get the + /// underlying cooked literal (representing the literal with the suffix + /// removed). + Expr *getCookedLiteral(); + const Expr *getCookedLiteral() const { + return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral(); + } + + /// getUDSuffixLoc - Returns the location of a ud-suffix in the expression. + /// For a string literal, there may be multiple identical suffixes. This + /// returns the first. + SourceLocation getUDSuffixLoc() const { return getRParenLoc(); } + + /// getUDSuffix - Returns the ud-suffix specified for this literal. + const IdentifierInfo *getUDSuffix() const; + + static bool classof(const Stmt *S) { + return S->getStmtClass() == UserDefinedLiteralClass; + } + static bool classof(const UserDefinedLiteral *) { return true; } + + friend class ASTStmtReader; + friend class ASTStmtWriter; +}; + /// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal. /// class CXXBoolLiteralExpr : public Expr { diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index aeb9d0508f..38a6a8515a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2037,6 +2037,7 @@ DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { }) DEF_TRAVERSE_STMT(CXXThisExpr, { }) DEF_TRAVERSE_STMT(CXXThrowExpr, { }) +DEF_TRAVERSE_STMT(UserDefinedLiteral, { }) DEF_TRAVERSE_STMT(DesignatedInitExpr, { }) DEF_TRAVERSE_STMT(ExtVectorElementExpr, { }) DEF_TRAVERSE_STMT(GNUNullExpr, { }) diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 5018ac1901..8d2e8f53a6 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -98,6 +98,7 @@ def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>; def CXXConstCastExpr : DStmt<CXXNamedCastExpr>; def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>; def CXXTypeidExpr : DStmt<Expr>; +def UserDefinedLiteral : DStmt<CallExpr>; def CXXBoolLiteralExpr : DStmt<Expr>; def CXXNullPtrLiteralExpr : DStmt<Expr>; def CXXThisExpr : DStmt<Expr>; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index bc7ecf5edd..ae4485c856 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2545,6 +2545,11 @@ public: const DeclarationNameInfo &NameInfo, NamedDecl *D); + ExprResult BuildLiteralOperatorCall(IdentifierInfo *UDSuffix, + SourceLocation UDSuffixLoc, + ArrayRef<Expr*> Args, + SourceLocation LitEndLoc); + ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); ExprResult ActOnNumericConstant(const Token &Tok); diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 0af1d3b0d1..a25851e0d5 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -1136,6 +1136,8 @@ namespace clang { EXPR_CXX_CONST_CAST, /// \brief A CXXFunctionalCastExpr record. EXPR_CXX_FUNCTIONAL_CAST, + /// \brief A UserDefinedLiteral record. + EXPR_USER_DEFINED_LITERAL, /// \brief A CXXBoolLiteralExpr record. EXPR_CXX_BOOL_LITERAL, EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr |