Record.push_back(D->getAccess());
Record.push_back(D->isModulePrivate());
Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
+
+ // If this declaration injected a name into a context different from its
+ // lexical context, and that context is an imported namespace, we need to
+ // update its visible declarations to include this name.
+ //
+ // This happens when we instantiate a class with a friend declaration or a
+ // function with a local extern declaration, for instance.
+ if (D->isOutOfLine()) {
+ auto *NS = dyn_cast<NamespaceDecl>(D->getDeclContext()->getRedeclContext());
+ if (NS && NS->isFromASTFile())
+ Writer.AddUpdatedDeclContext(NS);
+ }
}
void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
template<typename T> struct CommonTemplate {
enum E { a = 1, b = 2, c = 3 };
};
+
+namespace Std {
+ template<typename T> struct WithFriend {
+ friend bool operator!=(const WithFriend &A, const WithFriend &B) { return false; }
+ };
+}
c = d;
}
+bool testFriendInClassTemplate(Std::WithFriend<int> wfi) {
+ return wfi != wfi;
+}
+
// CHECK-GLOBAL: DeclarationName 'f'
// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
// CHECK-GLOBAL-NEXT: `-FunctionTemplate {{.*}} 'f'