typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
+ llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
public:
MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
return true;
}
+ unsigned getLambdaId(const CXXRecordDecl *RD) {
+ assert(RD->isLambda() && "RD must be a lambda!");
+ assert(!RD->isExternallyVisible() && "RD must not be visible!");
+ assert(RD->getLambdaManglingNumber() == 0 &&
+ "RD must not have a mangling number!");
+ std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator, bool>
+ Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
+ return Result.first->second;
+ }
+
private:
void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
};
break;
}
+ if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
+ if (Record->isLambda()) {
+ llvm::SmallString<10> Name("<lambda_");
+ unsigned LambdaId;
+ if (Record->getLambdaManglingNumber())
+ LambdaId = Record->getLambdaManglingNumber();
+ else
+ LambdaId = Context.getLambdaId(Record);
+
+ Name += llvm::utostr(LambdaId);
+ Name += ">";
+
+ mangleSourceName(Name);
+ break;
+ }
+ }
+
llvm::SmallString<64> Name("<unnamed-type-");
if (TD->hasDeclaratorForAnonDecl()) {
// Anonymous types with no tag or typedef get the name of their
} else {
// Otherwise, number the types using a $S prefix.
Name += "$S";
- Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
+ Name += llvm::utostr(Context.getAnonymousStructId(TD));
}
Name += ">";
mangleSourceName(Name.str());
void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
// <postfix> ::= <unqualified-name> [<postfix>]
// ::= <substitution> [<postfix>]
+ if (isLambda(ND))
+ return;
+
const DeclContext *DC = ND->getDeclContext();
while (!DC->isTranslationUnit()) {
// CHECK-DAG: ?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z
}
+
+inline int define_lambda() {
+ static auto lambda = [] { static int local; ++local; return local; };
+// First, we have the static local variable of type "<lambda_1>" inside of
+// "define_lambda".
+// CHECK-DAG: ?lambda@?1??define_lambda@@YAHXZ@4V<lambda_1>@@A
+// Next, we have the "operator()" for "<lambda_1>" which is inside of
+// "define_lambda".
+// CHECK-DAG: ??R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ
+// Finally, we have the local which is inside of "<lambda_1>" which is inside of
+// "define_lambda". Hooray.
+// CHECK-DAG: ?local@?2???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA
+ return lambda();
+}
+
+int call_lambda() {
+ return define_lambda();
+}