summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2013-08-22 01:49:11 +0000
committerFaisal Vali <faisalv@yahoo.com>2013-08-22 01:49:11 +0000
commitfd5277c0635f74bbdbb2daa3bb95e08f39db7d63 (patch)
tree776347516605949ffff1243cb3f85194200e9452 /clang/lib/Sema/TreeTransform.h
parentda68efdb689ee5b54bf3836add187b62b584de9a (diff)
downloadbcm5719-llvm-fd5277c0635f74bbdbb2daa3bb95e08f39db7d63.tar.gz
bcm5719-llvm-fd5277c0635f74bbdbb2daa3bb95e08f39db7d63.zip
Implement a rudimentary form of generic lambdas.
Specifically, the following features are not included in this commit: - any sort of capturing within generic lambdas - nested lambdas - conversion operator for captureless lambdas - ensuring all visitors are generic lambda aware As an example of what compiles: template <class F1, class F2> struct overload : F1, F2 { using F1::operator(); using F2::operator(); overload(F1 f1, F2 f2) : F1(f1), F2(f2) { } }; auto Recursive = [](auto Self, auto h, auto ... rest) { return 1 + Self(Self, rest...); }; auto Base = [](auto Self, auto h) { return 1; }; overload<decltype(Base), decltype(Recursive)> O(Base, Recursive); int num_params = O(O, 5, 3, "abc", 3.14, 'a'); Please see attached tests for more examples. Some implementation notes: - Add a new Declarator context => LambdaExprParameterContext to clang::Declarator to allow the use of 'auto' in declaring generic lambda parameters - Augment AutoType's constructor (similar to how variadic template-type-parameters ala TemplateTypeParmDecl are implemented) to accept an IsParameterPack to encode a generic lambda parameter pack. - Add various helpers to CXXRecordDecl to facilitate identifying and querying a closure class - LambdaScopeInfo (which maintains the current lambda's Sema state) was augmented to house the current depth of the template being parsed (id est the Parser calls Sema::RecordParsingTemplateParameterDepth) so that Sema::ActOnLambdaAutoParameter may use it to create the appropriate list of corresponding TemplateTypeParmDecl for each auto parameter identified within the generic lambda (also stored within the current LambdaScopeInfo). Additionally, a TemplateParameterList data-member was added to hold the invented TemplateParameterList AST node which will be much more useful once we teach TreeTransform how to transform generic lambdas. - SemaLambda.h was added to hold some common lambda utility functions (this file is likely to grow ...) - Teach Sema::ActOnStartOfFunctionDef to check whether it is being called to instantiate a generic lambda's call operator, and if so, push an appropriately prepared LambdaScopeInfo object on the stack. - Teach Sema::ActOnStartOfLambdaDefinition to set the return type of a lambda without a trailing return type to 'auto' in C++1y mode, and teach the return type deduction machinery in SemaStmt.cpp to process either C++11 and C++14 lambda's correctly depending on the flag. - various tests were added - but much more will be needed. A greatful thanks to all reviewers including Eli Friedman, James Dennett and the ever illuminating Richard Smith. And yet I am certain that I have allowed unidentified bugs to creep in; bugs, that I will do my best to slay, once identified! Thanks! llvm-svn: 188977
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r--clang/lib/Sema/TreeTransform.h26
1 files changed, 21 insertions, 5 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 9e5738394ea..6e69bdc5128 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -782,7 +782,10 @@ public:
// Note, IsDependent is always false here: we implicitly convert an 'auto'
// which has been deduced to a dependent type into an undeduced 'auto', so
// that we'll retry deduction after the transformation.
- return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto);
+ // FIXME: Can we assume the same about IsParameterPack?
+ return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto,
+ /*IsDependent*/ false,
+ /*IsParameterPack*/ false);
}
/// \brief Build a new template specialization type.
@@ -3494,7 +3497,9 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
Qs.removeObjCLifetime();
Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(),
Qs);
- Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto());
+ Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto(),
+ AutoTy->isDependentType(),
+ AutoTy->containsUnexpandedParameterPack());
TLB.TypeWasModifiedSafely(Result);
} else {
// Otherwise, complain about the addition of a qualifier to an
@@ -8193,6 +8198,14 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
+
+ // FIXME: Implement nested generic lambda transformations.
+ if (E->isGenericLambda()) {
+ getSema().Diag(E->getIntroducerRange().getBegin(),
+ diag::err_glambda_not_fully_implemented)
+ << " nested lambdas not implemented yet";
+ return ExprError();
+ }
// Transform the type of the lambda parameters and start the definition of
// the lambda itself.
TypeSourceInfo *MethodTy
@@ -8215,7 +8228,10 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
E->getCallOperator()->param_size(),
0, ParamTypes, &Params))
return ExprError();
-
+ getSema().PushLambdaScope();
+ LambdaScopeInfo *LSI = getSema().getCurLambda();
+ // TODO: Fix for nested lambdas
+ LSI->GLTemplateParameterList = 0;
// Build the call operator.
CXXMethodDecl *CallOperator
= getSema().startLambdaDefinition(Class, E->getIntroducerRange(),
@@ -8250,9 +8266,9 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
// Introduce the context of the call operator.
Sema::ContextRAII SavedContext(getSema(), CallOperator);
+ LambdaScopeInfo *const LSI = getSema().getCurLambda();
// Enter the scope of the lambda.
- sema::LambdaScopeInfo *LSI
- = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(),
+ getSema().buildLambdaScope(LSI, CallOperator, E->getIntroducerRange(),
E->getCaptureDefault(),
E->getCaptureDefaultLoc(),
E->hasExplicitParameters(),
OpenPOWER on IntegriCloud