Implement name mangling for lambda expressions that occur within the
default arguments of function parameters. This simple-sounding task is
complicated greatly by two issues:
(1) Default arguments aren't actually a real context, so we need to
maintain extra state within lambda expressions to track when a
lambda was actually in a default argument.
(2) At the time that we parse a default argument, the FunctionDecl
doesn't exist yet, so lambda closure types end up in the enclosing
context. It's not clear that we ever want to change that, so instead
we introduce the notion of the "effective" context of a declaration
for the purposes of name mangling.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151011 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index cbc5950..98664b2 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -765,7 +765,8 @@
ArrayRef<VarDecl *> ArrayIndexVars,
ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace,
- unsigned ManglingNumber)
+ unsigned ManglingNumber,
+ Decl *ContextDecl)
: Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
T->isDependentType(), T->isDependentType(), T->isDependentType(),
/*ContainsUnexpandedParameterPack=*/false),
@@ -787,6 +788,7 @@
Data.NumCaptures = NumCaptures;
Data.NumExplicitCaptures = 0;
Data.ManglingNumber = ManglingNumber;
+ Data.ContextDecl = ContextDecl;
Data.Captures = (Capture *)Context.Allocate(sizeof(Capture) * NumCaptures);
Capture *ToCapture = Data.Captures;
for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
@@ -827,7 +829,8 @@
ArrayRef<VarDecl *> ArrayIndexVars,
ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace,
- unsigned ManglingNumber) {
+ unsigned ManglingNumber,
+ Decl *ContextDecl) {
// Determine the type of the expression (i.e., the type of the
// function object we're creating).
QualType T = Context.getTypeDeclType(Class);
@@ -840,7 +843,7 @@
return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault,
Captures, ExplicitParams, ExplicitResultType,
CaptureInits, ArrayIndexVars, ArrayIndexStarts,
- ClosingBrace, ManglingNumber);
+ ClosingBrace, ManglingNumber, ContextDecl);
}
LambdaExpr *LambdaExpr::CreateDeserialized(ASTContext &C, unsigned NumCaptures,
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index a0bb6c7..93ebcc5 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -40,14 +40,38 @@
namespace {
+/// \brief Retrieve the declaration context that should be used when mangling
+/// the given declaration.
+static const DeclContext *getEffectiveDeclContext(const Decl *D) {
+ // The ABI assumes that lambda closure types that occur within
+ // default arguments live in the context of the function. However, due to
+ // the way in which Clang parses and creates function declarations, this is
+ // not the case: the lambda closure type ends up living in the context
+ // where the function itself resides, because the function declaration itself
+ // had not yet been created. Fix the context here.
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ if (RD->isLambda())
+ if (ParmVarDecl *ContextParam
+ = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
+ return ContextParam->getDeclContext();
+ }
+
+ return D->getDeclContext();
+}
+
+static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
+ return getEffectiveDeclContext(cast<Decl>(DC));
+}
+
static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) {
const DeclContext *DC = dyn_cast<DeclContext>(ND);
if (!DC)
- DC = ND->getDeclContext();
+ DC = getEffectiveDeclContext(ND);
while (!DC->isNamespace() && !DC->isTranslationUnit()) {
- if (isa<FunctionDecl>(DC->getParent()))
+ const DeclContext *Parent = getEffectiveDeclContext(cast<Decl>(DC));
+ if (isa<FunctionDecl>(Parent))
return dyn_cast<CXXRecordDecl>(DC);
- DC = DC->getParent();
+ DC = Parent;
}
return 0;
}
@@ -63,7 +87,7 @@
const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl);
return (fn ? getStructor(fn) : decl);
}
-
+
static const unsigned UnknownArity = ~0U;
class ItaniumMangleContext : public MangleContext {
@@ -279,6 +303,7 @@
void mangleUnscopedTemplateName(TemplateName);
void mangleSourceName(const IdentifierInfo *II);
void mangleLocalName(const NamedDecl *ND);
+ void mangleLambda(const CXXRecordDecl *Lambda);
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
bool NoFunction=false);
void mangleNestedName(const TemplateDecl *TD,
@@ -339,8 +364,8 @@
static bool isInCLinkageSpecification(const Decl *D) {
D = D->getCanonicalDecl();
- for (const DeclContext *DC = D->getDeclContext();
- !DC->isTranslationUnit(); DC = DC->getParent()) {
+ for (const DeclContext *DC = getEffectiveDeclContext(D);
+ !DC->isTranslationUnit(); DC = getEffectiveParentContext(DC)) {
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
}
@@ -372,17 +397,17 @@
// Variables at global scope with non-internal linkage are not mangled
if (!FD) {
- const DeclContext *DC = D->getDeclContext();
+ const DeclContext *DC = getEffectiveDeclContext(D);
// Check for extern variable declared locally.
if (DC->isFunctionOrMethod() && D->hasLinkage())
while (!DC->isNamespace() && !DC->isTranslationUnit())
- DC = DC->getParent();
+ DC = getEffectiveParentContext(DC);
if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)
return false;
}
// Class members are always mangled.
- if (D->getDeclContext()->isRecord())
+ if (getEffectiveDeclContext(D)->isRecord())
return true;
// C functions and "main" are not mangled.
@@ -465,7 +490,7 @@
static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
while (isa<LinkageSpecDecl>(DC)) {
- DC = DC->getParent();
+ DC = getEffectiveParentContext(DC);
}
return DC;
@@ -473,7 +498,8 @@
/// isStd - Return whether a given namespace is the 'std' namespace.
static bool isStd(const NamespaceDecl *NS) {
- if (!IgnoreLinkageSpecDecls(NS->getParent())->isTranslationUnit())
+ if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS))
+ ->isTranslationUnit())
return false;
const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
@@ -515,20 +541,20 @@
// ::= <unscoped-template-name> <template-args>
// ::= <local-name>
//
- const DeclContext *DC = ND->getDeclContext();
+ const DeclContext *DC = getEffectiveDeclContext(ND);
// If this is an extern variable declared locally, the relevant DeclContext
// is that of the containing namespace, or the translation unit.
if (isa<FunctionDecl>(DC) && ND->hasLinkage())
while (!DC->isNamespace() && !DC->isTranslationUnit())
- DC = DC->getParent();
+ DC = getEffectiveParentContext(DC);
else if (GetLocalClassDecl(ND)) {
mangleLocalName(ND);
return;
}
while (isa<LinkageSpecDecl>(DC))
- DC = DC->getParent();
+ DC = getEffectiveParentContext(DC);
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
// Check if we have a template.
@@ -554,7 +580,7 @@
void CXXNameMangler::mangleName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) {
- const DeclContext *DC = IgnoreLinkageSpecDecls(TD->getDeclContext());
+ const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD));
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
mangleUnscopedTemplateName(TD);
@@ -568,7 +594,7 @@
void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {
// <unscoped-name> ::= <unqualified-name>
// ::= St <unqualified-name> # ::std::
- if (isStdNamespace(ND->getDeclContext()))
+ if (isStdNamespace(getEffectiveDeclContext(ND)))
Out << "St";
mangleUnqualifiedName(ND);
@@ -1028,7 +1054,7 @@
// This naming convention is the same as that followed by GCC,
// though it shouldn't actually matter.
if (ND && ND->getLinkage() == InternalLinkage &&
- ND->getDeclContext()->isFileContext())
+ getEffectiveDeclContext(ND)->isFileContext())
Out << 'L';
mangleSourceName(II);
@@ -1089,28 +1115,7 @@
// <lambda-sig> ::= <parameter-type>+ # Parameter types or 'v' for 'void'.
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
if (Record->isLambda()) {
- // FIXME: Figure out if we're in a function body, default argument,
- // or initializer for a class member.
-
- Out << "Ul";
- DeclarationName Name
- = getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
- const FunctionProtoType *Proto
- = cast<CXXMethodDecl>(*Record->lookup(Name).first)->getType()->
- getAs<FunctionProtoType>();
- mangleBareFunctionType(Proto, /*MangleReturnType=*/false);
- Out << "E";
-
- // The number is omitted for the first closure type with a given
- // <lambda-sig> in a given context; it is n-2 for the nth closure type
- // (in lexical order) with that same <lambda-sig> and context.
- //
- // The AST keeps track of the number for us.
- if (unsigned Number = Record->getLambdaManglingNumber()) {
- if (Number > 1)
- mangleNumber(Number - 2);
- }
- Out << '_';
+ mangleLambda(Record);
break;
}
}
@@ -1243,8 +1248,10 @@
void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
// := Z <function encoding> E s [<discriminator>]
+ // <local-name> := Z <function encoding> E d [ <parameter number> ]
+ // _ <entity name>
// <discriminator> := _ <non-negative number>
- const DeclContext *DC = ND->getDeclContext();
+ const DeclContext *DC = getEffectiveDeclContext(ND);
if (isa<ObjCMethodDecl>(DC) && isa<FunctionDecl>(ND)) {
// Don't add objc method name mangling to locally declared function
mangleUnqualifiedName(ND);
@@ -1256,23 +1263,46 @@
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
mangleObjCMethodName(MD);
} else if (const CXXRecordDecl *RD = GetLocalClassDecl(ND)) {
- mangleFunctionEncoding(cast<FunctionDecl>(RD->getDeclContext()));
+ mangleFunctionEncoding(cast<FunctionDecl>(getEffectiveDeclContext(RD)));
Out << 'E';
+ // The parameter number is omitted for the last parameter, 0 for the
+ // second-to-last parameter, 1 for the third-to-last parameter, etc. The
+ // <entity name> will of course contain a <closure-type-name>: Its
+ // numbering will be local to the particular argument in which it appears
+ // -- other default arguments do not affect its encoding.
+ bool SkipDiscriminator = false;
+ if (RD->isLambda()) {
+ if (const ParmVarDecl *Parm
+ = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl())) {
+ if (const FunctionDecl *Func
+ = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
+ Out << 'd';
+ unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex();
+ if (Num > 1)
+ mangleNumber(Num - 2);
+ Out << '_';
+ SkipDiscriminator = true;
+ }
+ }
+ }
+
// Mangle the name relative to the closest enclosing function.
if (ND == RD) // equality ok because RD derived from ND above
mangleUnqualifiedName(ND);
else
mangleNestedName(ND, DC, true /*NoFunction*/);
- unsigned disc;
- if (Context.getNextDiscriminator(RD, disc)) {
- if (disc < 10)
- Out << '_' << disc;
- else
- Out << "__" << disc << '_';
+ if (!SkipDiscriminator) {
+ unsigned disc;
+ if (Context.getNextDiscriminator(RD, disc)) {
+ if (disc < 10)
+ Out << '_' << disc;
+ else
+ Out << "__" << disc << '_';
+ }
}
-
+
return;
}
else
@@ -1282,6 +1312,31 @@
mangleUnqualifiedName(ND);
}
+void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
+ // FIXME: Figure out if we're in a function body, default argument,
+ // or initializer for a class member.
+
+ Out << "Ul";
+ DeclarationName Name
+ = getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
+ const FunctionProtoType *Proto
+ = cast<CXXMethodDecl>(*Lambda->lookup(Name).first)->getType()->
+ getAs<FunctionProtoType>();
+ mangleBareFunctionType(Proto, /*MangleReturnType=*/false);
+ Out << "E";
+
+ // The number is omitted for the first closure type with a given
+ // <lambda-sig> in a given context; it is n-2 for the nth closure type
+ // (in lexical order) with that same <lambda-sig> and context.
+ //
+ // The AST keeps track of the number for us.
+ if (unsigned Number = Lambda->getLambdaManglingNumber()) {
+ if (Number > 1)
+ mangleNumber(Number - 2);
+ }
+ Out << '_';
+}
+
void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
switch (qualifier->getKind()) {
case NestedNameSpecifier::Global:
@@ -1322,13 +1377,13 @@
// ::= <substitution>
while (isa<LinkageSpecDecl>(DC))
- DC = DC->getParent();
+ DC = getEffectiveParentContext(DC);
if (DC->isTranslationUnit())
return;
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
- manglePrefix(DC->getParent(), NoFunction);
+ manglePrefix(getEffectiveParentContext(DC), NoFunction);
SmallString<64> Name;
llvm::raw_svector_ostream NameStream(Name);
Context.mangleBlock(Block, NameStream);
@@ -1352,7 +1407,7 @@
else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
mangleObjCMethodName(Method);
else {
- manglePrefix(DC->getParent(), NoFunction);
+ manglePrefix(getEffectiveParentContext(DC), NoFunction);
mangleUnqualifiedName(cast<NamedDecl>(DC));
}
@@ -1399,7 +1454,7 @@
return;
}
- manglePrefix(ND->getDeclContext());
+ manglePrefix(getEffectiveDeclContext(ND));
mangleUnqualifiedName(ND->getTemplatedDecl());
addSubstitution(ND);
}
@@ -3159,7 +3214,7 @@
if (!SD)
return false;
- if (!isStdNamespace(SD->getDeclContext()))
+ if (!isStdNamespace(getEffectiveDeclContext(SD)))
return false;
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
@@ -3201,7 +3256,7 @@
}
if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
- if (!isStdNamespace(TD->getDeclContext()))
+ if (!isStdNamespace(getEffectiveDeclContext(TD)))
return false;
// <substitution> ::= Sa # ::std::allocator
@@ -3219,7 +3274,7 @@
if (const ClassTemplateSpecializationDecl *SD =
dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
- if (!isStdNamespace(SD->getDeclContext()))
+ if (!isStdNamespace(getEffectiveDeclContext(SD)))
return false;
// <substitution> ::= Ss # ::std::basic_string<char,
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 51dc5c8..8ed0587 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -297,7 +297,8 @@
Scope::FunctionPrototypeScope|Scope::DeclScope);
for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
// Introduce the parameter into scope.
- Actions.ActOnDelayedCXXMethodParameter(getCurScope(), LM.DefaultArgs[I].Param);
+ Actions.ActOnDelayedCXXMethodParameter(getCurScope(),
+ LM.DefaultArgs[I].Param);
if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
// Save the current token position.
@@ -317,7 +318,8 @@
// The argument isn't actually potentially evaluated unless it is
// used.
EnterExpressionEvaluationContext Eval(Actions,
- Sema::PotentiallyEvaluatedIfUsed);
+ Sema::PotentiallyEvaluatedIfUsed,
+ LM.DefaultArgs[I].Param);
ExprResult DefArgResult(ParseAssignmentExpression());
if (DefArgResult.isInvalid())
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 0b98274..4193890 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -4520,7 +4520,8 @@
// The argument isn't actually potentially evaluated unless it is
// used.
EnterExpressionEvaluationContext Eval(Actions,
- Sema::PotentiallyEvaluatedIfUsed);
+ Sema::PotentiallyEvaluatedIfUsed,
+ Param);
ExprResult DefArgResult(ParseAssignmentExpression());
if (DefArgResult.isInvalid()) {
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 716ffd1..6a83518 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -111,7 +111,7 @@
&Context);
ExprEvalContexts.push_back(
- ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, false));
+ ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, false, 0));
FunctionScopes.push_back(new FunctionScopeInfo(Diags));
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3f1fabc..1008a3a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9275,11 +9275,13 @@
}
void
-Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
+Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
+ Decl *LambdaContextDecl) {
ExprEvalContexts.push_back(
ExpressionEvaluationContextRecord(NewContext,
ExprCleanupObjects.size(),
- ExprNeedsCleanups));
+ ExprNeedsCleanups,
+ LambdaContextDecl));
ExprNeedsCleanups = false;
if (!MaybeODRUseExprs.empty())
std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 6d54d40..047a284 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -485,6 +485,7 @@
ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
Scope *CurScope,
llvm::Optional<unsigned> ManglingNumber,
+ Decl *ContextDecl,
bool IsInstantiation) {
// Leave the expression-evaluation context.
DiscardCleanupsInEvaluationContext();
@@ -638,8 +639,34 @@
// If we don't already have a mangling number for this lambda expression,
// allocate one now.
if (!ManglingNumber) {
- // FIXME: Default arguments, data member initializers are special.
- ManglingNumber = Context.getLambdaManglingNumber(CallOperator);
+ ContextDecl = ExprEvalContexts.back().LambdaContextDecl;
+
+ // FIXME: Data member initializers.
+ enum ContextKind {
+ Normal,
+ DefaultArgument
+ } Kind = Normal;
+
+ // Default arguments of member function parameters that appear in a class
+ // definition receive special treatment. Identify them.
+ if (ParmVarDecl *Param = dyn_cast_or_null<ParmVarDecl>(ContextDecl)) {
+ if (const DeclContext *LexicalDC
+ = Param->getDeclContext()->getLexicalParent())
+ if (LexicalDC->isRecord())
+ Kind = DefaultArgument;
+ }
+
+ switch (Kind) {
+ case Normal:
+ ManglingNumber = Context.getLambdaManglingNumber(CallOperator);
+ ContextDecl = 0;
+ break;
+
+ case DefaultArgument:
+ ManglingNumber = ExprEvalContexts.back().getLambdaMangleContext()
+ .getManglingNumber(CallOperator);
+ break;
+ }
}
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
@@ -647,7 +674,7 @@
ExplicitParams, ExplicitResultType,
CaptureInits, ArrayIndexVars,
ArrayIndexStarts, Body->getLocEnd(),
- *ManglingNumber);
+ *ManglingNumber, ContextDecl);
// C++11 [expr.prim.lambda]p2:
// A lambda-expression shall not appear in an unevaluated operand
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 7e095f7..7e775f5 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -7768,10 +7768,14 @@
/*IsInstantiation=*/true);
return ExprError();
}
-
+
+ // Note: Once a lambda mangling number and context declaration have been
+ // assigned, they never change.
unsigned ManglingNumber = E->getLambdaClass()->getLambdaManglingNumber();
+ Decl *ContextDecl = E->getLambdaClass()->getLambdaContextDecl();
return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
/*CurScope=*/0, ManglingNumber,
+ ContextDecl,
/*IsInstantiation=*/true);
}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index b5e9c3d..c2a93b9 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1110,6 +1110,7 @@
Lambda.NumCaptures = Record[Idx++];
Lambda.NumExplicitCaptures = Record[Idx++];
Lambda.ManglingNumber = Record[Idx++];
+ Lambda.ContextDecl = ReadDecl(Record, Idx);
Lambda.Captures
= (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures);
Capture *ToCapture = Lambda.Captures;
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index add89ea..5c3a1e9 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -4333,6 +4333,7 @@
Record.push_back(Lambda.NumCaptures);
Record.push_back(Lambda.NumExplicitCaptures);
Record.push_back(Lambda.ManglingNumber);
+ AddDeclRef(Lambda.ContextDecl, Record);
for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
LambdaExpr::Capture &Capture = Lambda.Captures[I];
AddSourceLocation(Capture.getLocation(), Record);