clang-format uses clang's C++ parser to get a real understanding of the code, even in syntactical edge cases. Because of this, clang-format can provide more specific and contextual style rules that go beyond what astyle can do.
clang-format actually only uses clang's lexer, it does its own parsing. It does this so that it can be applied to code snipits and so that you don't have to provide the full include paths and command line options required to correctly parse the file.
In my experience, clang-format is much more usable in practice because it understands more of the syntax of C++ (rather than just relying on heuristics/pattern-matching) so it's much less prone to getting edge cases wrong.