diff options
| author | Edwin Vane <edwin.vane@intel.com> | 2013-05-09 20:03:52 +0000 |
|---|---|---|
| committer | Edwin Vane <edwin.vane@intel.com> | 2013-05-09 20:03:52 +0000 |
| commit | b40bf83eab6049a06159ad69b6422de9d6f3e2ee (patch) | |
| tree | a4c738b98c180ed312244584d116ced204879387 /clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp | |
| parent | acbb1a5db5791f8c4b6beb1a673d474589d9a9a5 (diff) | |
| download | bcm5719-llvm-b40bf83eab6049a06159ad69b6422de9d6f3e2ee.tar.gz bcm5719-llvm-b40bf83eab6049a06159ad69b6422de9d6f3e2ee.zip | |
Transform for loops over pseudo-arrays only if begin/end members exist
For loops using pseudo-arrays, classes that can be used like arrays from
the Loop Convert Transform's point of view, should only get transformed
if the pseudo-array class has begin()/end() members for the
range-based for-loop to call.
Free versions of begin()/end() should also be allowed but this is an
enhancement for another revision.
llvm-svn: 181539
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp')
| -rw-r--r-- | clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp index a7ca15f3eb3..d69f2a88811 100644 --- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp +++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopMatchers.cpp @@ -258,10 +258,57 @@ StatementMatcher makeIteratorLoopMatcher() { /// - If the end iterator variable 'g' is defined, it is the same as 'j' /// - The container's iterators would not be invalidated during the loop StatementMatcher makePseudoArrayLoopMatcher() { + // Test that the incoming type has a record declaration that has methods + // called 'begin' and 'end'. If the incoming type is const, then make sure + // these methods are also marked const. + // + // FIXME: To be completely thorough this matcher should also ensure the + // return type of begin/end is an iterator that dereferences to the same as + // what operator[] or at() returns. Such a test isn't likely to fail except + // for pathological cases. + // + // FIXME: Also, a record doesn't necessarily need begin() and end(). Free + // functions called begin() and end() taking the container as an argument + // are also allowed. + TypeMatcher RecordWithBeginEnd = + qualType(anyOf( + qualType( + isConstQualified(), + hasDeclaration( + recordDecl( + hasMethod( + methodDecl( + hasName("begin"), + isConst() + ) + ), + hasMethod( + methodDecl( + hasName("end"), + isConst() + ) + ) + ) + ) // hasDeclaration + ), // qualType + qualType( + unless(isConstQualified()), + hasDeclaration( + recordDecl( + hasMethod(hasName("begin")), + hasMethod(hasName("end")) + ) + ) + ) // qualType + ) + ); + StatementMatcher SizeCallMatcher = memberCallExpr(argumentCountIs(0), callee(methodDecl(anyOf(hasName("size"), - hasName("length"))))); + hasName("length")))), + on(anyOf(hasType(pointsTo(RecordWithBeginEnd)), + hasType(RecordWithBeginEnd)))); StatementMatcher EndInitMatcher = expr(anyOf( |

