diff options
| author | Alexis Hunt <alercah@gmail.com> | 2010-08-29 21:26:48 +0000 |
|---|---|---|
| committer | Alexis Hunt <alercah@gmail.com> | 2010-08-29 21:26:48 +0000 |
| commit | 79eb5469e04aa8906262619d1f7a3a71ba5dbd94 (patch) | |
| tree | 6c9a4252f73fd27626204a4de22602dc8802d849 /clang/lib/Sema/SemaExprCXX.cpp | |
| parent | c843fca2fde772c85010123556d3e3abeb75b9ab (diff) | |
| download | bcm5719-llvm-79eb5469e04aa8906262619d1f7a3a71ba5dbd94.tar.gz bcm5719-llvm-79eb5469e04aa8906262619d1f7a3a71ba5dbd94.zip | |
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.
llvm-svn: 112458
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 5720d931b66..344196cc6ff 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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); +} |

