For -Wconsumed, walk the namespaces to find if the top most namespace is "std"

to determine if a move function is the std::move function.  This allows functions
like std::__1::move to also be treated a the move function.

llvm-svn: 197445
This commit is contained in:
Richard Trieu 2013-12-17 00:40:40 +00:00
parent 8dcf98547e
commit c689691618
2 changed files with 21 additions and 2 deletions

View File

@ -605,14 +605,25 @@ void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) {
}
}
static bool isStdNamespace(const DeclContext *DC) {
if (!DC->isNamespace()) return false;
while (DC->getParent()->isNamespace())
DC = DC->getParent();
const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
return ND && ND->getName() == "std" &&
ND->getDeclContext()->isTranslationUnit();
}
void ConsumedStmtVisitor::VisitCallExpr(const CallExpr *Call) {
if (const FunctionDecl *FunDecl =
dyn_cast_or_null<FunctionDecl>(Call->getDirectCallee())) {
// Special case for the std::move function.
// TODO: Make this more specific. (Deferred)
if (FunDecl->getQualifiedNameAsString() == "std::move" &&
Call->getNumArgs() == 1) {
if (Call->getNumArgs() == 1 &&
FunDecl->getNameAsString() == "move" &&
isStdNamespace(FunDecl->getDeclContext())) {
forwardInfo(Call->getArg(0), Call);
return;
}

View File

@ -798,6 +798,12 @@ namespace std {
void move();
template<class T>
void move(T&&);
namespace __1 {
void move();
template<class T>
void move(T&&);
}
}
namespace PR18260 {
@ -810,5 +816,7 @@ namespace PR18260 {
x.move();
std::move();
std::move(x);
std::__1::move();
std::__1::move(x);
}
} // end namespace PR18260