summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorAlexis Hunt <alercah@gmail.com>2010-08-29 21:26:48 +0000
committerAlexis Hunt <alercah@gmail.com>2010-08-29 21:26:48 +0000
commit79eb5469e04aa8906262619d1f7a3a71ba5dbd94 (patch)
tree6c9a4252f73fd27626204a4de22602dc8802d849 /clang/lib/Sema/SemaExprCXX.cpp
parentc843fca2fde772c85010123556d3e3abeb75b9ab (diff)
downloadbcm5719-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.cpp58
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);
+}
OpenPOWER on IntegriCloud