summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2014-04-03 16:32:21 +0000
committerFaisal Vali <faisalv@yahoo.com>2014-04-03 16:32:21 +0000
commitb90b211eea7274bba1588e86695a55bdd6490b5b (patch)
tree17b976b2b573b7c96c86c93eb28b62e01b9c5ed8 /clang/lib/AST/Decl.cpp
parent265f2f04409969ab30700a3a3070bb9137309428 (diff)
downloadbcm5719-llvm-b90b211eea7274bba1588e86695a55bdd6490b5b.tar.gz
bcm5719-llvm-b90b211eea7274bba1588e86695a55bdd6490b5b.zip
Teach getTemplateInstantiationPattern to deal with generic lambdas.
No functionality change. When determining the pattern for instantiating a generic lambda call operator specialization - we must not go drilling down for the 'prototype' (i.e. as written) pattern - rather we must use our partially transformed pattern (whose DeclRefExprs are wired correctly to any enclosing lambda's decls that should be mapped correctly in a local instantiation scope) that is the templated pattern of the specialization's primary template (even though the primary template might be instantiated from a 'prototype' member-template). Previously, the drilling down was haltted by marking the instantiated-from primary template as a member-specialization (incorrectly). This prompted Richard to remark (http://llvm-reviews.chandlerc.com/D1784?id=4687#inline-10272) "It's a bit nasty to (essentially) set this bit incorrectly. Can you put the check into getTemplateInstantiationPattern instead?" In my reckless youth, I chose to ignore that comment. With the passage of time, I have come to learn the value of bowing to the will of the angry Gods ;) llvm-svn: 205543
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r--clang/lib/AST/Decl.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 13681ddf559..15410f0e9ba 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
@@ -2830,14 +2831,34 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
// Handle class scope explicit specialization special case.
if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
return getClassScopeSpecializationPattern();
-
+
+ // If this is a generic lambda call operator specialization, its
+ // instantiation pattern is always its primary template's pattern
+ // even if its primary template was instantiated from another
+ // member template (which happens with nested generic lambdas).
+ // Since a lambda's call operator's body is transformed eagerly,
+ // we don't have to go hunting for a prototype definition template
+ // (i.e. instantiated-from-member-template) to use as an instantiation
+ // pattern.
+
+ if (isGenericLambdaCallOperatorSpecialization(
+ dyn_cast<CXXMethodDecl>(this))) {
+ assert(getPrimaryTemplate() && "A generic lambda specialization must be "
+ "generated from a primary call operator "
+ "template");
+ assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
+ "A generic lambda call operator template must always have a body - "
+ "even if instantiated from a prototype (i.e. as written) member "
+ "template");
+ return getPrimaryTemplate()->getTemplatedDecl();
+ }
+
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
while (Primary->getInstantiatedFromMemberTemplate()) {
// If we have hit a point where the user provided a specialization of
// this template, we're done looking.
if (Primary->isMemberSpecialization())
break;
-
Primary = Primary->getInstantiatedFromMemberTemplate();
}
OpenPOWER on IntegriCloud