<string> forward declares a template for the output operator, but this template is nowhere defined. Instead <ostream> provides an inline definition for that template. This leads to the following program not linking: x.cc --- #include <iostream> void foo(std::ostream &); int main() { foo(std::cout); } y.cc --- #include <string> #include <iosfwd> void foo(std::ostream &os) { os << std::string("a"); } The linker will give an undefined symbol for the operator <<. The reason is that <string> forward declares the template which is not defined neither in <string> nor in the librarie's string.cc. Because of the forward declaration y.cc happily compiles with an undefined reference in the obj-file. When including <ostream> in y.cc, the linker is successful since there is a inline template definition in <ostream>. According to my reading of the standard this is wrong - the defintion should be in <string> or string.cc should have an instantiation of the template for char and wchar_t. This is probably an upstream issue?
This definitely looks like an upstream issue. Would you mind filing a bug on LLVM's bug tracker?