r222646 - Adding 4 ASTMatchers: typedefDecl, isInMainFile, isInSystemFile, isInFileMatchingName

Aaron Ballman aaron at aaronballman.com
Mon Nov 24 07:51:01 PST 2014


On Mon, Nov 24, 2014 at 4:10 AM, Manuel Klimek <klimek at google.com> wrote:
> Author: klimek
> Date: Mon Nov 24 03:10:56 2014
> New Revision: 222646
>
> URL: http://llvm.org/viewvc/llvm-project?rev=222646&view=rev
> Log:
> Adding 4 ASTMatchers: typedefDecl, isInMainFile, isInSystemFile, isInFileMatchingName
>
> Summary:
> Often one is only interested in matches within the main-file or matches
> that are not within a system-header, for which this patch adds
> isInMainFile and isInSystemFile. They take no arguments and narrow down
> the matches.
>
> The isInFileMatchingName is mainly thought for interactive
> clang-query-sessions, to make a matcher more specific without restarting
> the session with the files you are interested in for that moment. It
> takes a string that will be used as regular-expression to match the
> filename of where the matched node is expanded.
>
> Patch by Hendrik von Prince.
>
> Modified:
>     cfe/trunk/docs/LibASTMatchersReference.html
>     cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
>     cfe/trunk/include/clang/Tooling/Tooling.h
>     cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
>     cfe/trunk/lib/Tooling/Tooling.cpp
>     cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
>     cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h
>
> Modified: cfe/trunk/docs/LibASTMatchersReference.html
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/docs/LibASTMatchersReference.html (original)
> +++ cfe/trunk/docs/LibASTMatchersReference.html Mon Nov 24 03:10:56 2014
> @@ -307,6 +307,16 @@ Example matches X, Z
>  </pre></td></tr>
>
>
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('typedefDecl0')"><a name="typedefDecl0Anchor">typedefDecl</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefDecl.html">TypedefDecl</a>>...</td></tr>
> +<tr><td colspan="4" class="doc" id="typedefDecl0"><pre>Matches typedef declarations.
> +
> +Given
> +  typedef int X;
> +typedefDecl()
> +  matches "typedef int X"
> +</pre></td></tr>
> +
> +
>  <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('unresolvedUsingValueDecl0')"><a name="unresolvedUsingValueDecl0Anchor">unresolvedUsingValueDecl</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingValueDecl.html">UnresolvedUsingValueDecl</a>>...</td></tr>
>  <tr><td colspan="4" class="doc" id="unresolvedUsingValueDecl0"><pre>Matches unresolved using value declarations.
>
> @@ -339,6 +349,15 @@ usingDirectiveDecl()
>    matches using namespace X </pre></td></tr>
>
>
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('valueDecl0')"><a name="valueDecl0Anchor">valueDecl</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>>...</td></tr>
> +<tr><td colspan="4" class="doc" id="valueDecl0"><pre>Matches any value declaration.
> +
> +Example matches A, B, C and F
> +  enum X { A, B, C };
> +  void F();
> +</pre></td></tr>
> +
> +
>  <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('varDecl0')"><a name="varDecl0Anchor">varDecl</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>...</td></tr>
>  <tr><td colspan="4" class="doc" id="varDecl0"><pre>Matches variable declarations.
>
> @@ -1654,6 +1673,48 @@ f.
>  </pre></td></tr>
>
>
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isExpansionInFileMatching0')"><a name="isExpansionInFileMatching0Anchor">isExpansionInFileMatching</a></td><td>std::string RegExp</td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInFileMatching0"><pre>Matches AST nodes that were expanded within files whose name is
> +partially matching a given regex.
> +
> +Example matches Y but not X
> +    (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
> +  #include "ASTMatcher.h"
> +  class X {};
> +ASTMatcher.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isExpansionInMainFile0')"><a name="isExpansionInMainFile0Anchor">isExpansionInMainFile</a></td><td></td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInMainFile0"><pre>Matches AST nodes that were expanded within the main-file.
> +
> +Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
> +  #include <Y.h>
> +  class X {};
> +Y.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isExpansionInSystemHeader0')"><a name="isExpansionInSystemHeader0Anchor">isExpansionInSystemHeader</a></td><td></td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInSystemHeader0"><pre>Matches AST nodes that were expanded within system-header-files.
> +
> +Example matches Y but not X
> +    (matcher = recordDecl(isExpansionInSystemHeader())
> +  #include <SystemHeader.h>
> +  class X {};
> +SystemHeader.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
>  <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
>  <tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a declaration that has been implicitly added
>  by the compiler (eg. implicit defaultcopy constructors).
> @@ -1858,7 +1919,7 @@ memberExpr(isArrow())
>  </pre></td></tr>
>
>
> -<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr>
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string  Name</td></tr>
>  <tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes that have the specified name.
>
>  Supports specifying enclosing namespaces or classes by prefixing the name
> @@ -1990,6 +2051,48 @@ and reference to that variable declarati
>  </pre></td></tr>
>
>
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isExpansionInFileMatching1')"><a name="isExpansionInFileMatching1Anchor">isExpansionInFileMatching</a></td><td>std::string RegExp</td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInFileMatching1"><pre>Matches AST nodes that were expanded within files whose name is
> +partially matching a given regex.
> +
> +Example matches Y but not X
> +    (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
> +  #include "ASTMatcher.h"
> +  class X {};
> +ASTMatcher.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isExpansionInMainFile1')"><a name="isExpansionInMainFile1Anchor">isExpansionInMainFile</a></td><td></td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInMainFile1"><pre>Matches AST nodes that were expanded within the main-file.
> +
> +Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
> +  #include <Y.h>
> +  class X {};
> +Y.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isExpansionInSystemHeader1')"><a name="isExpansionInSystemHeader1Anchor">isExpansionInSystemHeader</a></td><td></td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInSystemHeader1"><pre>Matches AST nodes that were expanded within system-header-files.
> +
> +Example matches Y but not X
> +    (matcher = recordDecl(isExpansionInSystemHeader())
> +  #include <SystemHeader.h>
> +  class X {};
> +SystemHeader.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
>  <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isInTemplateInstantiation0')"><a name="isInTemplateInstantiation0Anchor">isInTemplateInstantiation</a></td><td></td></tr>
>  <tr><td colspan="4" class="doc" id="isInTemplateInstantiation0"><pre>Matches statements inside of a template instantiation.
>
> @@ -2061,6 +2164,48 @@ classTemplateSpecializationDecl(template
>  </pre></td></tr>
>
>
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('isExpansionInFileMatching2')"><a name="isExpansionInFileMatching2Anchor">isExpansionInFileMatching</a></td><td>std::string RegExp</td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInFileMatching2"><pre>Matches AST nodes that were expanded within files whose name is
> +partially matching a given regex.
> +
> +Example matches Y but not X
> +    (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
> +  #include "ASTMatcher.h"
> +  class X {};
> +ASTMatcher.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('isExpansionInMainFile2')"><a name="isExpansionInMainFile2Anchor">isExpansionInMainFile</a></td><td></td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInMainFile2"><pre>Matches AST nodes that were expanded within the main-file.
> +
> +Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
> +  #include <Y.h>
> +  class X {};
> +Y.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
> +<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('isExpansionInSystemHeader2')"><a name="isExpansionInSystemHeader2Anchor">isExpansionInSystemHeader</a></td><td></td></tr>
> +<tr><td colspan="4" class="doc" id="isExpansionInSystemHeader2"><pre>Matches AST nodes that were expanded within system-header-files.
> +
> +Example matches Y but not X
> +    (matcher = recordDecl(isExpansionInSystemHeader())
> +  #include <SystemHeader.h>
> +  class X {};
> +SystemHeader.h:
> +  class Y {};
> +
> +Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>
> +</pre></td></tr>
> +
> +
>  <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('equalsBoundNode2')"><a name="equalsBoundNode2Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
>  <tr><td colspan="4" class="doc" id="equalsBoundNode2"><pre>Matches if a node equals a previously bound node.
>
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Nov 24 03:10:56 2014
> @@ -47,6 +47,7 @@
>
>  #include "clang/AST/DeclFriend.h"
>  #include "clang/AST/DeclTemplate.h"
> +#include "clang/AST/ASTContext.h"
>  #include "clang/ASTMatchers/ASTMatchersInternal.h"
>  #include "clang/ASTMatchers/ASTMatchersMacros.h"
>  #include "llvm/ADT/Twine.h"
> @@ -142,6 +143,97 @@ typedef internal::Matcher<NestedNameSpec
>  /// Usable as: Any Matcher
>  inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
>
> +/// \brief Matches typedef declarations.
> +///
> +/// Given
> +/// \code
> +///   typedef int X;
> +/// \endcode
> +/// typedefDecl()
> +///   matches "typedef int X"
> +const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
> +
> +/// \brief Matches AST nodes that were expanded within the main-file.
> +///
> +/// Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
> +/// \code
> +///   #include <Y.h>
> +///   class X {};
> +/// \endcode
> +/// Y.h:
> +/// \code
> +///   class Y {};
> +/// \endcode
> +///
> +/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
> +AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
> +                        AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
> +                                                          TypeLoc)) {
> +  auto &SourceManager = Finder->getASTContext().getSourceManager();
> +  return SourceManager.isInMainFile(
> +      SourceManager.getExpansionLoc(Node.getLocStart()));
> +}
> +
> +/// \brief Matches AST nodes that were expanded within system-header-files.
> +///
> +/// Example matches Y but not X
> +///     (matcher = recordDecl(isExpansionInSystemHeader())
> +/// \code
> +///   #include <SystemHeader.h>
> +///   class X {};
> +/// \endcode
> +/// SystemHeader.h:
> +/// \code
> +///   class Y {};
> +/// \endcode
> +///
> +/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
> +AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
> +                        AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
> +                                                          TypeLoc)) {
> +  auto &SourceManager = Finder->getASTContext().getSourceManager();
> +  auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
> +  if (ExpansionLoc.isInvalid()) {
> +    return false;
> +  }
> +  return SourceManager.isInSystemHeader(ExpansionLoc);
> +}
> +
> +/// \brief Matches AST nodes that were expanded within files whose name is
> +/// partially matching a given regex.
> +///
> +/// Example matches Y but not X
> +///     (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
> +/// \code
> +///   #include "ASTMatcher.h"
> +///   class X {};
> +/// \endcode
> +/// ASTMatcher.h:
> +/// \code
> +///   class Y {};
> +/// \endcode
> +///
> +/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
> +AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
> +                          AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
> +                                                            TypeLoc),
> +                          std::string, RegExp) {
> +  auto &SourceManager = Finder->getASTContext().getSourceManager();
> +  auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
> +  if (ExpansionLoc.isInvalid()) {
> +    return false;
> +  }
> +  auto FileEntry =
> +      SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
> +  if (!FileEntry) {
> +    return false;
> +  }
> +
> +  auto Filename = FileEntry->getName();
> +  llvm::Regex RE(RegExp);
> +  return RE.match(Filename);
> +}
> +
>  /// \brief Matches declarations.
>  ///
>  /// Examples matches \c X, \c C, and the friend declaration inside \c C;
>
> Modified: cfe/trunk/include/clang/Tooling/Tooling.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Tooling/Tooling.h (original)
> +++ cfe/trunk/include/clang/Tooling/Tooling.h Mon Nov 24 03:10:56 2014
> @@ -143,6 +143,10 @@ inline std::unique_ptr<FrontendActionFac
>  bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
>                     const Twine &FileName = "input.cc");
>
> +/// The first part of the pair is the filename, the second part the
> +/// file-content.
> +typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
> +
>  /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
>  ///        with additional other flags.
>  ///
> @@ -152,9 +156,10 @@ bool runToolOnCode(clang::FrontendAction
>  /// \param FileName The file name which 'Code' will be mapped as.
>  ///
>  /// \return - True if 'ToolAction' was successfully executed.
> -bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
> -                           const std::vector<std::string> &Args,
> -                           const Twine &FileName = "input.cc");
> +bool runToolOnCodeWithArgs(
> +    clang::FrontendAction *ToolAction, const Twine &Code,
> +    const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
> +    const FileContentMappings &VirtualMappedFiles = FileContentMappings());
>
>  /// \brief Builds an AST for 'Code'.
>  ///
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Mon Nov 24 03:10:56 2014
> @@ -242,7 +242,10 @@ RegistryMaps::RegistryMaps() {
>    REGISTER_MATCHER(isExpr);
>    REGISTER_MATCHER(isExternC);
>    REGISTER_MATCHER(isImplicit);
> +  REGISTER_MATCHER(isExpansionInFileMatching);
> +  REGISTER_MATCHER(isExpansionInMainFile);
>    REGISTER_MATCHER(isInstantiated);
> +  REGISTER_MATCHER(isExpansionInSystemHeader);
>    REGISTER_MATCHER(isInteger);
>    REGISTER_MATCHER(isIntegral);
>    REGISTER_MATCHER(isInTemplateInstantiation);
> @@ -314,6 +317,7 @@ RegistryMaps::RegistryMaps() {
>    REGISTER_MATCHER(to);
>    REGISTER_MATCHER(tryStmt);
>    REGISTER_MATCHER(type);
> +  REGISTER_MATCHER(typedefDecl);
>    REGISTER_MATCHER(typedefType);
>    REGISTER_MATCHER(typeLoc);
>    REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
>
> Modified: cfe/trunk/lib/Tooling/Tooling.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Tooling/Tooling.cpp (original)
> +++ cfe/trunk/lib/Tooling/Tooling.cpp Mon Nov 24 03:10:56 2014
> @@ -123,17 +123,25 @@ getSyntaxOnlyToolArgs(const std::vector<
>
>  bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
>                             const std::vector<std::string> &Args,
> -                           const Twine &FileName) {
> +                           const Twine &FileName,
> +                           const FileContentMappings &VirtualMappedFiles) {
> +
>    SmallString<16> FileNameStorage;
>    StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
>    llvm::IntrusiveRefCntPtr<FileManager> Files(
>        new FileManager(FileSystemOptions()));
> -  ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction,
> -                            Files.get());
> +  ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef),
> +                            ToolAction, Files.get());
>
>    SmallString<1024> CodeStorage;
>    Invocation.mapVirtualFile(FileNameRef,
>                              Code.toNullTerminatedStringRef(CodeStorage));
> +
> +  for (auto &FilenameWithContent : VirtualMappedFiles) {
> +    Invocation.mapVirtualFile(FilenameWithContent.first,
> +                              FilenameWithContent.second);
> +  }
> +
>    return Invocation.run();
>  }
>
>
> Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
> +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Mon Nov 24 03:10:56 2014
> @@ -4625,5 +4625,46 @@ TEST(EqualsBoundNodeMatcher, UnlessDesce
>            .bind("data")));
>  }
>
> +TEST(TypeDefDeclMatcher, Match) {
> +  EXPECT_TRUE(matches("typedef int typedefDeclTest;",
> +                      typedefDecl(hasName("typedefDeclTest"))));
> +}
> +
> +TEST(Matcher, IsExpansionInMainFileMatcher) {
> +  EXPECT_TRUE(matches("class X {};",
> +                      recordDecl(hasName("X"), isExpansionInMainFile())));
> +  EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
> +  EXPECT_TRUE(matchesConditionally("#include <other>\n",
> +                                   recordDecl(isExpansionInMainFile()), false,
> +                                   "-isystem/", {{"/other", "class X {};"}}));
> +}
> +
> +TEST(Matcher, IsExpansionInSystemHeader) {
> +  EXPECT_TRUE(matchesConditionally(
> +      "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
> +      "-isystem/", {{"/other", "class X {};"}}));
> +  EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
> +                                   recordDecl(isExpansionInSystemHeader()),
> +                                   false, "-I/", {{"/other", "class X {};"}}));
> +  EXPECT_TRUE(notMatches("class X {};",
> +                         recordDecl(isExpansionInSystemHeader())));
> +  EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
> +}
> +
> +TEST(Matcher, IsExpansionInFileMatching) {
> +  EXPECT_TRUE(matchesConditionally(
> +      "#include <foo>\n"
> +      "#include <bar>\n"
> +      "class X {};",
> +      recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
> +      "-isystem/", {{"/foo", "class A {};"}, {"/bar", "class B {};"}}));
> +  EXPECT_TRUE(matchesConditionally(
> +      "#include <foo>\n"
> +      "#include <bar>\n"
> +      "class X {};",
> +      recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
> +      "-isystem/", {{"/foo", "class A {};"}, {"/bar", "class B {};"}}));
> +}
> +
>  } // end namespace ast_matchers
>  } // end namespace clang
>
> Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h?rev=222646&r1=222645&r2=222646&view=diff
> ==============================================================================
> --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h (original)
> +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h Mon Nov 24 03:10:56 2014
> @@ -22,6 +22,7 @@ using clang::tooling::buildASTFromCodeWi
>  using clang::tooling::newFrontendActionFactory;
>  using clang::tooling::runToolOnCodeWithArgs;
>  using clang::tooling::FrontendActionFactory;
> +using clang::tooling::FileContentMappings;
>
>  class BoundNodesCallback {
>  public:
> @@ -58,10 +59,10 @@ private:
>  };
>
>  template <typename T>
> -testing::AssertionResult matchesConditionally(const std::string &Code,
> -                                              const T &AMatcher,
> -                                              bool ExpectMatch,
> -                                              llvm::StringRef CompileArg) {
> +testing::AssertionResult matchesConditionally(
> +    const std::string &Code, const T &AMatcher, bool ExpectMatch,
> +    llvm::StringRef CompileArg,
> +    const FileContentMappings &VirtualMappedFiles = FileContentMappings()) {
>    bool Found = false, DynamicFound = false;
>    MatchFinder Finder;
>    VerifyMatch VerifyFound(nullptr, &Found);
> @@ -73,7 +74,8 @@ testing::AssertionResult matchesConditio
>        newFrontendActionFactory(&Finder));
>    // Some tests use typeof, which is a gnu extension.
>    std::vector<std::string> Args(1, CompileArg);
> -  if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) {
> +  if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, "input.cc",
> +                             VirtualMappedFiles)) {
>      return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
>    }
>    if (Found != DynamicFound) {
>

I am getting failed unit tests from this on Windows, built with MSVC:

61>  Running the Clang regression tests
61>  -- Testing: 7831 tests, 32 threads --
61>  FAIL: Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInFileMatching
(7145 of 7831)
61>  ******************** TEST 'Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInFileMatching'
FAILED ********************
61>  Note: Google Test filter = Matcher.IsExpansionInFileMatching
61>
61>  [==========] Running 1 test from 1 test case.
61>
61>  [----------] Global test environment set-up.
61>
61>  [----------] 1 test from Matcher
61>
61>  [ RUN      ] Matcher.IsExpansionInFileMatching
61>
61>E:\llvm\llvm\tools\clang\unittests\ASTMatchers\ASTMatchersTest.cpp(4660):
error : Value of: matchesConditionally( "#include <foo>\n" "#include
<bar>\n" "class X {};", recordDecl(isExpansionInFileMatching("b.*"),
hasName("B")), true, "-isystem/", {{"/foo", "class A {};"}, {"/bar",
"class B {};"}})
61>
61>    Actual: false (Parsing error in "#include <foo>
61>
61>  #include <bar>
61>
61>  class X {};")
61>
61>  Expected: true
61>
61>E:\llvm\llvm\tools\clang\unittests\ASTMatchers\ASTMatchersTest.cpp(4666):
error : Value of: matchesConditionally( "#include <foo>\n" "#include
<bar>\n" "class X {};", recordDecl(isExpansionInFileMatching("f.*"),
hasName("X")), false, "-isystem/", {{"/foo", "class A {};"}, {"/bar",
"class B {};"}})
61>
61>    Actual: false (Parsing error in "#include <foo>
61>
61>  #include <bar>
61>
61>  class X {};")
61>
61>  Expected: true
61>
61>  [  FAILED  ] Matcher.IsExpansionInFileMatching (36 ms)
61>
61>  [----------] 1 test from Matcher (36 ms total)
61>
61>
61>
61>  [----------] Global test environment tear-down
61>
61>  [==========] 1 test from 1 test case ran. (36 ms total)
61>
61>  [  PASSED  ] 0 tests.
61>
61>  [  FAILED  ] 1 test, listed below:
61>
61>  [  FAILED  ] Matcher.IsExpansionInFileMatching
61>
61>
61>
61>   1 FAILED TEST
61>
61>  input.cc:1:10: fatal error: 'foo' file not found
61>
61>  #include <foo>
61>
61>           ^
61>
61>  1 error generated.
61>
61>  input.cc:1:10: fatal error: 'foo' file not found
61>
61>  #include <foo>
61>
61>           ^
61>
61>  1 error generated.
61>
61>
61>  ********************
61>  FAIL: Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInMainFileMatcher
(7146 of 7831)
61>  ******************** TEST 'Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInMainFileMatcher'
FAILED ********************
61>  Note: Google Test filter = Matcher.IsExpansionInMainFileMatcher
61>
61>  [==========] Running 1 test from 1 test case.
61>
61>  [----------] Global test environment set-up.
61>
61>  [----------] 1 test from Matcher
61>
61>  [ RUN      ] Matcher.IsExpansionInMainFileMatcher
61>
61>E:\llvm\llvm\tools\clang\unittests\ASTMatchers\ASTMatchersTest.cpp(4639):
error : Value of: matchesConditionally("#include <other>\n",
recordDecl(isExpansionInMainFile()), false, "-isystem/", {{"/other",
"class X {};"}})
61>
61>    Actual: false (Parsing error in "#include <other>
61>
61>  ")
61>
61>  Expected: true
61>
61>  [  FAILED  ] Matcher.IsExpansionInMainFileMatcher (64 ms)
61>
61>  [----------] 1 test from Matcher (64 ms total)
61>
61>
61>
61>  [----------] Global test environment tear-down
61>
61>  [==========] 1 test from 1 test case ran. (65 ms total)
61>
61>  [  PASSED  ] 0 tests.
61>
61>  [  FAILED  ] 1 test, listed below:
61>
61>  [  FAILED  ] Matcher.IsExpansionInMainFileMatcher
61>
61>
61>
61>   1 FAILED TEST
61>
61>  input.cc:1:10: fatal error: 'other' file not found
61>
61>  #include <other>
61>
61>           ^
61>
61>  1 error generated.
61>
61>
61>  ********************
61>  FAIL: Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInSystemHeader
(7152 of 7831)
61>  ******************** TEST 'Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInSystemHeader'
FAILED ********************
61>  Note: Google Test filter = Matcher.IsExpansionInSystemHeader
61>
61>  [==========] Running 1 test from 1 test case.
61>
61>  [----------] Global test environment set-up.
61>
61>  [----------] 1 test from Matcher
61>
61>  [ RUN      ] Matcher.IsExpansionInSystemHeader
61>
61>E:\llvm\llvm\tools\clang\unittests\ASTMatchers\ASTMatchersTest.cpp(4645):
error : Value of: matchesConditionally( "#include \"other\"\n",
recordDecl(isExpansionInSystemHeader()), true, "-isystem/",
{{"/other", "class X {};"}})
61>
61>    Actual: false (Parsing error in "#include "other"
61>
61>  ")
61>
61>  Expected: true
61>
61>E:\llvm\llvm\tools\clang\unittests\ASTMatchers\ASTMatchersTest.cpp(4648):
error : Value of: matchesConditionally("#include \"other\"\n",
recordDecl(isExpansionInSystemHeader()), false, "-I/", {{"/other",
"class X {};"}})
61>
61>    Actual: false (Parsing error in "#include "other"
61>
61>  ")
61>
61>  Expected: true
61>
61>  [  FAILED  ] Matcher.IsExpansionInSystemHeader (91 ms)
61>
61>  [----------] 1 test from Matcher (91 ms total)
61>
61>
61>
61>  [----------] Global test environment tear-down
61>
61>  [==========] 1 test from 1 test case ran. (91 ms total)
61>
61>  [  PASSED  ] 0 tests.
61>
61>  [  FAILED  ] 1 test, listed below:
61>
61>  [  FAILED  ] Matcher.IsExpansionInSystemHeader
61>
61>
61>
61>   1 FAILED TEST
61>
61>  input.cc:1:10: fatal error: 'other' file not found
61>
61>  #include "other"
61>
61>           ^
61>
61>  1 error generated.
61>
61>  input.cc:1:10: fatal error: 'other' file not found
61>
61>  #include "other"
61>
61>           ^
61>
61>  1 error generated.
61>
61>
61>  ********************
61>
61>  Testing Time: 111.19s
61>  ********************
61>  Failing Tests (3):
61>      Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInFileMatching
61>      Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInMainFileMatcher
61>      Clang-Unit ::
ASTMatchers/Debug/ASTMatchersTests.exe/Matcher.IsExpansionInSystemHeader
61>
61>    Expected Passes    : 7745
61>    Expected Failures  : 19
61>    Unsupported Tests  : 64
61>    Unexpected Failures: 3

~Aaron




More information about the cfe-commits mailing list