[PATCH] Clang-Modernize.Pass-By-Value: Fix removing of namespace in parameter type
Guillaume Papin
guillaume.papin at epitech.eu
Thu Sep 5 14:53:53 PDT 2013
- Remove test for space before commas.
Hi revane, arielbernal, tareqsiraj,
http://llvm-reviews.chandlerc.com/D1600
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1600?vs=4074&id=4075#toc
Files:
clang-modernize/PassByValue/PassByValueActions.cpp
clang-modernize/PassByValue/PassByValueMatchers.cpp
test/clang-modernize/PassByValue/basic.cpp
Index: clang-modernize/PassByValue/PassByValueActions.cpp
===================================================================
--- clang-modernize/PassByValue/PassByValueActions.cpp
+++ clang-modernize/PassByValue/PassByValueActions.cpp
@@ -113,16 +113,20 @@
collectParamDecls(Ctor, ParamDecl, AllParamDecls);
// Generate all replacements for the params.
- llvm::SmallVector<Replacement, 2> ParamReplaces(AllParamDecls.size());
+ llvm::SmallVector<Replacement, 2> ParamReplaces;
for (unsigned I = 0, E = AllParamDecls.size(); I != E; ++I) {
TypeLoc ParamTL = AllParamDecls[I]->getTypeSourceInfo()->getTypeLoc();
+ ReferenceTypeLoc RefTL = ParamTL.getAs<ReferenceTypeLoc>();
SourceRange Range(AllParamDecls[I]->getLocStart(), ParamTL.getLocEnd());
CharSourceRange CharRange = Lexer::makeFileCharRange(
CharSourceRange::getTokenRange(Range), SM, LangOptions());
- TypeLoc ValueTypeLoc = ParamTL;
+
+ // do not generate a replacement when the parameter is already a value
+ if (RefTL.isNull())
+ continue;
+
// transform non-value parameters (e.g: const-ref) to values
- if (!ParamTL.getNextTypeLoc().isNull())
- ValueTypeLoc = ParamTL.getNextTypeLoc();
+ TypeLoc ValueTypeLoc = RefTL.getPointeeLoc();
llvm::SmallString<32> ValueStr = Lexer::getSourceText(
CharSourceRange::getTokenRange(ValueTypeLoc.getSourceRange()), SM,
LangOptions());
@@ -136,7 +140,7 @@
// 'const Foo ¶m' -> 'Foo param'
// ~~~~~~~~~~~ ~~~^
ValueStr += ' ';
- ParamReplaces[I] = Replacement(SM, CharRange, ValueStr);
+ ParamReplaces.push_back(Replacement(SM, CharRange, ValueStr));
}
// Reject the changes if the the risk level is not acceptable.
Index: clang-modernize/PassByValue/PassByValueMatchers.cpp
===================================================================
--- clang-modernize/PassByValue/PassByValueMatchers.cpp
+++ clang-modernize/PassByValue/PassByValueMatchers.cpp
@@ -63,15 +63,29 @@
using namespace clang;
using namespace clang::ast_matchers;
+static TypeMatcher constRefType() {
+ return lValueReferenceType(pointee(isConstQualified()));
+}
+
+static TypeMatcher nonConstValueType() {
+ return qualType(unless(anyOf(referenceType(), isConstQualified())));
+}
+
DeclarationMatcher makePassByValueCtorParamMatcher() {
return constructorDecl(
forEachConstructorInitializer(ctorInitializer(
// Clang builds a CXXConstructExpr only when it knowns which
// constructor will be called. In dependent contexts a ParenListExpr
// is generated instead of a CXXConstructExpr, filtering out templates
// automatically for us.
withInitializer(constructExpr(
- has(declRefExpr(to(parmVarDecl().bind(PassByValueParamId)))),
+ has(declRefExpr(to(
+ parmVarDecl(hasType(qualType(
+ // match only const-ref or a non-const value
+ // parameters, rvalues and const-values
+ // shouldn't be modified.
+ anyOf(constRefType(), nonConstValueType()))))
+ .bind(PassByValueParamId)))),
hasDeclaration(constructorDecl(
isNonDeletedCopyConstructor(),
hasDeclContext(recordDecl(isMoveConstructible())))))))
Index: test/clang-modernize/PassByValue/basic.cpp
===================================================================
--- test/clang-modernize/PassByValue/basic.cpp
+++ test/clang-modernize/PassByValue/basic.cpp
@@ -150,7 +150,7 @@
// Test with a const-value parameter
struct P {
P(const Movable M) : M(M) {}
- // CHECK: P(Movable M) : M(std::move(M)) {}
+ // CHECK: P(const Movable M) : M(M) {}
Movable M;
};
@@ -166,3 +166,20 @@
Movable C;
double D;
};
+
+// Test that value-parameters with a nested name specifier are left as-is
+namespace ns_R {
+typedef ::Movable RMovable;
+}
+struct R {
+ R(ns_R::RMovable M) : M(M) {}
+ // CHECK: R(ns_R::RMovable M) : M(std::move(M)) {}
+ ns_R::RMovable M;
+};
+
+// Test with rvalue parameter
+struct S {
+ S(Movable &&M) : M(M) {}
+ // CHECK: S(Movable &&M) : M(M) {}
+ Movable M;
+};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1600.3.patch
Type: text/x-patch
Size: 4282 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130905/a2a9ccb8/attachment.bin>
More information about the cfe-commits
mailing list