[PATCH] D21767: Fix instantiation of friend function templates

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 14 14:21:17 PDT 2018


rjmccall added a comment.

Oh, I see.  The code currently tries to work with just the specialization and the pattern.  To do the instantiation, we have to find template arguments for the context in which the pattern appears.  For function temploids that aren't defined in a friend declaration, we can just consider the semantic DC hierarchy of the specialization, which will be the same across all redeclarations.  For function temploids that *are* defined in a friend declaration, we have to look at the lexical DC of the declaration that was actually instantiated from the class temploid that defined the friend function, which isn't necessarily the specialization because it might have been redeclared after the friend function was instantiated.  So your patch is mostly just changing the find-the-pattern lookup to remember that lexical DC when we find a pattern this way, which seems sensible.  Richard should look over the actual lookup-algorithm changes.



================
Comment at: include/clang/AST/Decl.h:2443
+  /// defined in a friend declaration, this parameter is assigned pointer to the
+  /// class containing the friend declaration.
+  ///
----------------
"If this is non-null and the pattern is a friend function declaration, this is set to the class containing the friend declaration."


================
Comment at: lib/AST/Decl.cpp:3389
+      if (Orig->getFriendObjectKind() != Decl::FOK_None) {
+        if (auto *RDC = dyn_cast<CXXRecordDecl>(D->getLexicalDeclContext()))
+          Host = RDC;
----------------
I don't think this can fail; a friend should always be lexically nested in a class.


================
Comment at: lib/AST/Decl.cpp:3399
+        return Def;
+      }
+    }
----------------
It's unfortunate that this needs to walk the redeclaration chain itself looking for definitions.  Can't you just call `getDefinition` to find the definition and then run your extra checks on that?


================
Comment at: lib/AST/Decl.cpp:3444
+    if (MFD->getFriendObjectKind() != Decl::FOK_None)
+      if (auto *DC = dyn_cast<CXXRecordDecl>(getLexicalDeclContext()))
+        if (HostForFriend)
----------------
Same observation.


Repository:
  rC Clang

https://reviews.llvm.org/D21767





More information about the cfe-commits mailing list