diff options
author | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2010-08-29 21:26:48 +0000 |
---|---|---|
committer | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2010-08-29 21:26:48 +0000 |
commit | 0016d519b831859526b79405cdae4c64c73731c8 (patch) | |
tree | 135462aff4053d3400e0046e831e518d598f6569 /lib/Sema/SemaExprCXX.cpp | |
parent | aba480862485ea1140a81f25c23f43bb080edc90 (diff) |
Implement C++0x user-defined string literals.
The extra data stored on user-defined literal Tokens is stored in extra
allocated memory, which is managed by the PreprocessorLexer because there isn't
a better place to put it that makes sure it gets deallocated, but only after
it's used up. My testing has shown no significant slowdown as a result, but
independent testing would be appreciated.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112458 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 5720d931b6..344196cc6f 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3057,3 +3057,61 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) { if (!FullExpr) return ExprError(); return MaybeCreateCXXExprWithTemporaries(FullExpr); } + +ExprResult Sema::BuildUDStringLiteralExpr(Scope *S, StringLiteral *SL, + unsigned L, IdentifierInfo *II) { + DeclarationName DN = Context.DeclarationNames.getCXXLiteralOperatorName(II); + + LookupResult R(*this, DN, SL->getLocStart(), LookupOrdinaryName); + LookupName(R, S); + + llvm::APInt APL(Context.getTypeSize(Context.getSizeType()), L); + + Expr *Args[2]; + Args[0] = SL; + Args[1] = new (Context) IntegerLiteral(Context, APL, Context.getSizeType(), + SourceLocation()); + + OverloadCandidateSet CandidateSet(SL->getLocStart()); + AddFunctionCandidates(R.asUnresolvedSet(), Args, 2, CandidateSet); + OverloadCandidateSet::iterator Best; + switch (CandidateSet.BestViableFunction(*this, SL->getLocStart(), Best)) { + case OR_Ambiguous: + llvm_unreachable("UD literals should not have ambiguous overloads"); + return ExprError(); + case OR_No_Viable_Function: + Diag(SL->getLocStart(), diag::err_literal_operator_overload) + << SL->getSourceRange() << II->getName(); + return ExprError(); + case OR_Deleted: + Diag(SL->getLocStart(), diag::err_literal_operator_deleted) + << SL->getSourceRange() << II->getName(); + //FIXME: Note the deleted function + return ExprError(); + case OR_Success: + break; + } + + assert(Best->Function && "Literal operator function not a real function"); + FunctionDecl *FD = Best->Function; + + ExprResult InputInit + = PerformCopyInitialization(InitializedEntity::InitializeParameter( + FD->getParamDecl(0)), + SourceLocation(), Owned(SL)); + if (InputInit.isInvalid()) + return ExprError(); + Args[0] = InputInit.takeAs<Expr>(); + + QualType ResultTy = FD->getResultType().getNonReferenceType(); + Expr *Fn = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + UsualUnaryConversions(Fn); + + UDLiteralExpr *E = new (Context) UDLiteralExpr(Context, SL, Fn, Args, 2, + ResultTy); + + if (CheckCallReturnType(FD->getResultType(), SL->getLocStart(), E, FD)) + return ExprError(); + + return MaybeBindToTemporary(E); +} |