aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorSean Hunt <scshunt@csclub.uwaterloo.ca>2010-08-29 21:26:48 +0000
committerSean Hunt <scshunt@csclub.uwaterloo.ca>2010-08-29 21:26:48 +0000
commit0016d519b831859526b79405cdae4c64c73731c8 (patch)
tree135462aff4053d3400e0046e831e518d598f6569 /lib/Sema/SemaExprCXX.cpp
parentaba480862485ea1140a81f25c23f43bb080edc90 (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.cpp58
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);
+}