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 /lib/Sema/SemaExpr.cpp | |
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 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 6b753a1342..7d99732e68 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1172,10 +1172,27 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { ArrayType::Normal, 0); // Pass &StringTokLocs[0], StringTokLocs.size() to factory! - return Owned(StringLiteral::Create(Context, Literal.GetString(), - Kind, Literal.Pascal, StrTy, - &StringTokLocs[0], - StringTokLocs.size())); + StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), + Kind, Literal.Pascal, StrTy, + &StringTokLocs[0], + StringTokLocs.size()); + if (Literal.getUDSuffix().empty()) + return Owned(Lit); + + // We're building a user-defined literal. + IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix()); + SourceLocation UDSuffixLoc = StringTokLocs[0]; + // FIXME: = Literal.getUDSuffixLoc(getSourceManager()); + + // C++11 [lex.ext]p5: The literal L is treated as a call of the form + // operator "" X (str, len) + QualType SizeType = Context.getSizeType(); + llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars()); + IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType, + StringTokLocs[0]); + Expr *Args[] = { Lit, LenArg }; + return BuildLiteralOperatorCall(UDSuffix, UDSuffixLoc, Args, + StringTokLocs.back()); } ExprResult |