Skip to content

Commit e7c9753

Browse files
committed
Visit lambdas right after FunctionDecl
1 parent 950ed7e commit e7c9753

File tree

4 files changed

+50
-8
lines changed

4 files changed

+50
-8
lines changed

clang/lib/AST/DeclTemplate.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,8 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
349349
GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
350350
CommonBasePtr->LazySpecializations = nullptr;
351351
unsigned SpecSize = (*Specs++).getRawValue();
352-
// Load the specializations in reverse order so that the most recent
353-
// specialization are visited first so they become canonical declarations.
354-
// This order matches the order in which namelookup discovers declarations
355-
// coming from modules.
356-
for (unsigned I = SpecSize; I != 0; --I)
357-
(void)Context.getExternalSource()->GetExternalDecl(Specs[I - 1]);
352+
for (unsigned I = 0; I != SpecSize; ++I)
353+
(void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
358354
}
359355
}
360356

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,15 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
11551155
for (unsigned I = 0; I != NumParams; ++I)
11561156
Params.push_back(readDeclAs<ParmVarDecl>());
11571157
FD->setParams(Reader.getContext(), Params);
1158+
1159+
// For the first decl read all lambdas inside, otherwise skip them.
1160+
unsigned NumLambdas = Record.readInt();
1161+
if (FD->isFirstDecl()) {
1162+
for (unsigned I = 0; I != NumLambdas; ++I)
1163+
readDecl();
1164+
} else {
1165+
(void)Record.readIntArray(NumLambdas);
1166+
}
11581167
}
11591168

11601169
void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/Expr.h"
1919
#include "clang/AST/OpenMPClause.h"
2020
#include "clang/AST/PrettyDeclStackTrace.h"
21+
#include "clang/AST/StmtVisitor.h"
2122
#include "clang/Basic/SourceManager.h"
2223
#include "clang/Serialization/ASTReader.h"
2324
#include "clang/Serialization/ASTRecordWriter.h"
@@ -625,6 +626,33 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
625626
: QualType());
626627
}
627628

629+
static llvm::SmallVector<const Decl *, 2> collectLambdas(FunctionDecl *D) {
630+
struct LambdaCollector : public ConstStmtVisitor<LambdaCollector> {
631+
llvm::SmallVectorImpl<const Decl *> &Lambdas;
632+
633+
LambdaCollector(llvm::SmallVectorImpl<const Decl *> &Lambdas)
634+
: Lambdas(Lambdas) {}
635+
636+
void VisitLambdaExpr(const LambdaExpr *E) {
637+
VisitStmt(E);
638+
Lambdas.push_back(E->getLambdaClass());
639+
}
640+
641+
void VisitStmt(const Stmt *S) {
642+
if (!S)
643+
return;
644+
for (const Stmt *Child : S->children())
645+
if (Child)
646+
Visit(Child);
647+
}
648+
};
649+
650+
llvm::SmallVector<const Decl *, 2> Lambdas;
651+
if (D->hasBody())
652+
LambdaCollector(Lambdas).VisitStmt(D->getBody());
653+
return Lambdas;
654+
}
655+
628656
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
629657
static_assert(DeclContext::NumFunctionDeclBits == 44,
630658
"You need to update the serializer after you change the "
@@ -764,6 +792,15 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
764792
Record.push_back(D->param_size());
765793
for (auto *P : D->parameters())
766794
Record.AddDeclRef(P);
795+
796+
// Store references to all lambda decls inside function to load them
797+
// immediately after loading the function to make sure that canonical
798+
// decls for lambdas will be from the same module.
799+
llvm::SmallVector<const Decl *, 2> Lambdas = collectLambdas(D);
800+
Record.push_back(Lambdas.size());
801+
for (const auto *L : Lambdas)
802+
Record.AddDeclRef(L);
803+
767804
Code = serialization::DECL_FUNCTION;
768805
}
769806

clang/test/Modules/odr_hash.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3084,8 +3084,8 @@ struct S5 {
30843084
};
30853085
#else
30863086
S5 s5;
3087-
// expected-error@first.h:* {{'PointersAndReferences::S5::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S5' in module 'SecondModule'}}
3088-
// expected-note@second.h:* {{declaration of 'x' does not match}}
3087+
// expected-error@second.h:* {{'PointersAndReferences::S5::x' from module 'SecondModule' is not present in definition of 'PointersAndReferences::S5' in module 'FirstModule'}}
3088+
// expected-note@first.h:* {{declaration of 'x' does not match}}
30893089
#endif
30903090

30913091
#if defined(FIRST)

0 commit comments

Comments
 (0)