Skip to content

Commit da50ff8

Browse files
committedNov 24, 2014
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. llvm-svn: 222646
1 parent b2a6e74 commit da50ff8

File tree

7 files changed

+309
-12
lines changed

7 files changed

+309
-12
lines changed
 

‎clang/docs/LibASTMatchersReference.html

+146-1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,16 @@ <h2 id="decl-matchers">Node Matchers</h2>
307307
</pre></td></tr>
308308

309309

310+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</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>&gt;...</td></tr>
311+
<tr><td colspan="4" class="doc" id="typedefDecl0"><pre>Matches typedef declarations.
312+
313+
Given
314+
typedef int X;
315+
typedefDecl()
316+
matches "typedef int X"
317+
</pre></td></tr>
318+
319+
310320
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</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>&gt;...</td></tr>
311321
<tr><td colspan="4" class="doc" id="unresolvedUsingValueDecl0"><pre>Matches unresolved using value declarations.
312322

@@ -339,6 +349,15 @@ <h2 id="decl-matchers">Node Matchers</h2>
339349
matches using namespace X </pre></td></tr>
340350

341351

352+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</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>&gt;...</td></tr>
353+
<tr><td colspan="4" class="doc" id="valueDecl0"><pre>Matches any value declaration.
354+
355+
Example matches A, B, C and F
356+
enum X { A, B, C };
357+
void F();
358+
</pre></td></tr>
359+
360+
342361
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</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>&gt;...</td></tr>
343362
<tr><td colspan="4" class="doc" id="varDecl0"><pre>Matches variable declarations.
344363

@@ -1654,6 +1673,48 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
16541673
</pre></td></tr>
16551674

16561675

1676+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isExpansionInFileMatching0')"><a name="isExpansionInFileMatching0Anchor">isExpansionInFileMatching</a></td><td>std::string RegExp</td></tr>
1677+
<tr><td colspan="4" class="doc" id="isExpansionInFileMatching0"><pre>Matches AST nodes that were expanded within files whose name is
1678+
partially matching a given regex.
1679+
1680+
Example matches Y but not X
1681+
(matcher = recordDecl(isExpansionInFileMatching("AST.*"))
1682+
#include "ASTMatcher.h"
1683+
class X {};
1684+
ASTMatcher.h:
1685+
class Y {};
1686+
1687+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
1688+
</pre></td></tr>
1689+
1690+
1691+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isExpansionInMainFile0')"><a name="isExpansionInMainFile0Anchor">isExpansionInMainFile</a></td><td></td></tr>
1692+
<tr><td colspan="4" class="doc" id="isExpansionInMainFile0"><pre>Matches AST nodes that were expanded within the main-file.
1693+
1694+
Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
1695+
#include &lt;Y.h&gt;
1696+
class X {};
1697+
Y.h:
1698+
class Y {};
1699+
1700+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
1701+
</pre></td></tr>
1702+
1703+
1704+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isExpansionInSystemHeader0')"><a name="isExpansionInSystemHeader0Anchor">isExpansionInSystemHeader</a></td><td></td></tr>
1705+
<tr><td colspan="4" class="doc" id="isExpansionInSystemHeader0"><pre>Matches AST nodes that were expanded within system-header-files.
1706+
1707+
Example matches Y but not X
1708+
(matcher = recordDecl(isExpansionInSystemHeader())
1709+
#include &lt;SystemHeader.h&gt;
1710+
class X {};
1711+
SystemHeader.h:
1712+
class Y {};
1713+
1714+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
1715+
</pre></td></tr>
1716+
1717+
16571718
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
16581719
<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a declaration that has been implicitly added
16591720
by the compiler (eg. implicit defaultcopy constructors).
@@ -1858,7 +1919,7 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
18581919
</pre></td></tr>
18591920

18601921

1861-
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt;</td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr>
1922+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt;</td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr>
18621923
<tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes that have the specified name.
18631924

18641925
Supports specifying enclosing namespaces or classes by prefixing the name
@@ -1990,6 +2051,48 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
19902051
</pre></td></tr>
19912052

19922053

2054+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('isExpansionInFileMatching1')"><a name="isExpansionInFileMatching1Anchor">isExpansionInFileMatching</a></td><td>std::string RegExp</td></tr>
2055+
<tr><td colspan="4" class="doc" id="isExpansionInFileMatching1"><pre>Matches AST nodes that were expanded within files whose name is
2056+
partially matching a given regex.
2057+
2058+
Example matches Y but not X
2059+
(matcher = recordDecl(isExpansionInFileMatching("AST.*"))
2060+
#include "ASTMatcher.h"
2061+
class X {};
2062+
ASTMatcher.h:
2063+
class Y {};
2064+
2065+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
2066+
</pre></td></tr>
2067+
2068+
2069+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('isExpansionInMainFile1')"><a name="isExpansionInMainFile1Anchor">isExpansionInMainFile</a></td><td></td></tr>
2070+
<tr><td colspan="4" class="doc" id="isExpansionInMainFile1"><pre>Matches AST nodes that were expanded within the main-file.
2071+
2072+
Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
2073+
#include &lt;Y.h&gt;
2074+
class X {};
2075+
Y.h:
2076+
class Y {};
2077+
2078+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
2079+
</pre></td></tr>
2080+
2081+
2082+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('isExpansionInSystemHeader1')"><a name="isExpansionInSystemHeader1Anchor">isExpansionInSystemHeader</a></td><td></td></tr>
2083+
<tr><td colspan="4" class="doc" id="isExpansionInSystemHeader1"><pre>Matches AST nodes that were expanded within system-header-files.
2084+
2085+
Example matches Y but not X
2086+
(matcher = recordDecl(isExpansionInSystemHeader())
2087+
#include &lt;SystemHeader.h&gt;
2088+
class X {};
2089+
SystemHeader.h:
2090+
class Y {};
2091+
2092+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
2093+
</pre></td></tr>
2094+
2095+
19932096
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('isInTemplateInstantiation0')"><a name="isInTemplateInstantiation0Anchor">isInTemplateInstantiation</a></td><td></td></tr>
19942097
<tr><td colspan="4" class="doc" id="isInTemplateInstantiation0"><pre>Matches statements inside of a template instantiation.
19952098

@@ -2061,6 +2164,48 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
20612164
</pre></td></tr>
20622165

20632166

2167+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('isExpansionInFileMatching2')"><a name="isExpansionInFileMatching2Anchor">isExpansionInFileMatching</a></td><td>std::string RegExp</td></tr>
2168+
<tr><td colspan="4" class="doc" id="isExpansionInFileMatching2"><pre>Matches AST nodes that were expanded within files whose name is
2169+
partially matching a given regex.
2170+
2171+
Example matches Y but not X
2172+
(matcher = recordDecl(isExpansionInFileMatching("AST.*"))
2173+
#include "ASTMatcher.h"
2174+
class X {};
2175+
ASTMatcher.h:
2176+
class Y {};
2177+
2178+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
2179+
</pre></td></tr>
2180+
2181+
2182+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('isExpansionInMainFile2')"><a name="isExpansionInMainFile2Anchor">isExpansionInMainFile</a></td><td></td></tr>
2183+
<tr><td colspan="4" class="doc" id="isExpansionInMainFile2"><pre>Matches AST nodes that were expanded within the main-file.
2184+
2185+
Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
2186+
#include &lt;Y.h&gt;
2187+
class X {};
2188+
Y.h:
2189+
class Y {};
2190+
2191+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
2192+
</pre></td></tr>
2193+
2194+
2195+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('isExpansionInSystemHeader2')"><a name="isExpansionInSystemHeader2Anchor">isExpansionInSystemHeader</a></td><td></td></tr>
2196+
<tr><td colspan="4" class="doc" id="isExpansionInSystemHeader2"><pre>Matches AST nodes that were expanded within system-header-files.
2197+
2198+
Example matches Y but not X
2199+
(matcher = recordDecl(isExpansionInSystemHeader())
2200+
#include &lt;SystemHeader.h&gt;
2201+
class X {};
2202+
SystemHeader.h:
2203+
class Y {};
2204+
2205+
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;
2206+
</pre></td></tr>
2207+
2208+
20642209
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>&gt;</td><td class="name" onclick="toggle('equalsBoundNode2')"><a name="equalsBoundNode2Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
20652210
<tr><td colspan="4" class="doc" id="equalsBoundNode2"><pre>Matches if a node equals a previously bound node.
20662211

‎clang/include/clang/ASTMatchers/ASTMatchers.h

+92
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
#include "clang/AST/DeclFriend.h"
4949
#include "clang/AST/DeclTemplate.h"
50+
#include "clang/AST/ASTContext.h"
5051
#include "clang/ASTMatchers/ASTMatchersInternal.h"
5152
#include "clang/ASTMatchers/ASTMatchersMacros.h"
5253
#include "llvm/ADT/Twine.h"
@@ -142,6 +143,97 @@ typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
142143
/// Usable as: Any Matcher
143144
inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
144145

146+
/// \brief Matches typedef declarations.
147+
///
148+
/// Given
149+
/// \code
150+
/// typedef int X;
151+
/// \endcode
152+
/// typedefDecl()
153+
/// matches "typedef int X"
154+
const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
155+
156+
/// \brief Matches AST nodes that were expanded within the main-file.
157+
///
158+
/// Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile())
159+
/// \code
160+
/// #include <Y.h>
161+
/// class X {};
162+
/// \endcode
163+
/// Y.h:
164+
/// \code
165+
/// class Y {};
166+
/// \endcode
167+
///
168+
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
169+
AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
170+
AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
171+
TypeLoc)) {
172+
auto &SourceManager = Finder->getASTContext().getSourceManager();
173+
return SourceManager.isInMainFile(
174+
SourceManager.getExpansionLoc(Node.getLocStart()));
175+
}
176+
177+
/// \brief Matches AST nodes that were expanded within system-header-files.
178+
///
179+
/// Example matches Y but not X
180+
/// (matcher = recordDecl(isExpansionInSystemHeader())
181+
/// \code
182+
/// #include <SystemHeader.h>
183+
/// class X {};
184+
/// \endcode
185+
/// SystemHeader.h:
186+
/// \code
187+
/// class Y {};
188+
/// \endcode
189+
///
190+
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
191+
AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
192+
AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
193+
TypeLoc)) {
194+
auto &SourceManager = Finder->getASTContext().getSourceManager();
195+
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
196+
if (ExpansionLoc.isInvalid()) {
197+
return false;
198+
}
199+
return SourceManager.isInSystemHeader(ExpansionLoc);
200+
}
201+
202+
/// \brief Matches AST nodes that were expanded within files whose name is
203+
/// partially matching a given regex.
204+
///
205+
/// Example matches Y but not X
206+
/// (matcher = recordDecl(isExpansionInFileMatching("AST.*"))
207+
/// \code
208+
/// #include "ASTMatcher.h"
209+
/// class X {};
210+
/// \endcode
211+
/// ASTMatcher.h:
212+
/// \code
213+
/// class Y {};
214+
/// \endcode
215+
///
216+
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
217+
AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
218+
AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
219+
TypeLoc),
220+
std::string, RegExp) {
221+
auto &SourceManager = Finder->getASTContext().getSourceManager();
222+
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
223+
if (ExpansionLoc.isInvalid()) {
224+
return false;
225+
}
226+
auto FileEntry =
227+
SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
228+
if (!FileEntry) {
229+
return false;
230+
}
231+
232+
auto Filename = FileEntry->getName();
233+
llvm::Regex RE(RegExp);
234+
return RE.match(Filename);
235+
}
236+
145237
/// \brief Matches declarations.
146238
///
147239
/// Examples matches \c X, \c C, and the friend declaration inside \c C;

‎clang/include/clang/Tooling/Tooling.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
143143
bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
144144
const Twine &FileName = "input.cc");
145145

146+
/// The first part of the pair is the filename, the second part the
147+
/// file-content.
148+
typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
149+
146150
/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
147151
/// with additional other flags.
148152
///
@@ -152,9 +156,10 @@ bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
152156
/// \param FileName The file name which 'Code' will be mapped as.
153157
///
154158
/// \return - True if 'ToolAction' was successfully executed.
155-
bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
156-
const std::vector<std::string> &Args,
157-
const Twine &FileName = "input.cc");
159+
bool runToolOnCodeWithArgs(
160+
clang::FrontendAction *ToolAction, const Twine &Code,
161+
const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
162+
const FileContentMappings &VirtualMappedFiles = FileContentMappings());
158163

159164
/// \brief Builds an AST for 'Code'.
160165
///

‎clang/lib/ASTMatchers/Dynamic/Registry.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ RegistryMaps::RegistryMaps() {
242242
REGISTER_MATCHER(isExpr);
243243
REGISTER_MATCHER(isExternC);
244244
REGISTER_MATCHER(isImplicit);
245+
REGISTER_MATCHER(isExpansionInFileMatching);
246+
REGISTER_MATCHER(isExpansionInMainFile);
245247
REGISTER_MATCHER(isInstantiated);
248+
REGISTER_MATCHER(isExpansionInSystemHeader);
246249
REGISTER_MATCHER(isInteger);
247250
REGISTER_MATCHER(isIntegral);
248251
REGISTER_MATCHER(isInTemplateInstantiation);
@@ -314,6 +317,7 @@ RegistryMaps::RegistryMaps() {
314317
REGISTER_MATCHER(to);
315318
REGISTER_MATCHER(tryStmt);
316319
REGISTER_MATCHER(type);
320+
REGISTER_MATCHER(typedefDecl);
317321
REGISTER_MATCHER(typedefType);
318322
REGISTER_MATCHER(typeLoc);
319323
REGISTER_MATCHER(unaryExprOrTypeTraitExpr);

‎clang/lib/Tooling/Tooling.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,25 @@ getSyntaxOnlyToolArgs(const std::vector<std::string> &ExtraArgs,
123123

124124
bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
125125
const std::vector<std::string> &Args,
126-
const Twine &FileName) {
126+
const Twine &FileName,
127+
const FileContentMappings &VirtualMappedFiles) {
128+
127129
SmallString<16> FileNameStorage;
128130
StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
129131
llvm::IntrusiveRefCntPtr<FileManager> Files(
130132
new FileManager(FileSystemOptions()));
131-
ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction,
132-
Files.get());
133+
ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef),
134+
ToolAction, Files.get());
133135

134136
SmallString<1024> CodeStorage;
135137
Invocation.mapVirtualFile(FileNameRef,
136138
Code.toNullTerminatedStringRef(CodeStorage));
139+
140+
for (auto &FilenameWithContent : VirtualMappedFiles) {
141+
Invocation.mapVirtualFile(FilenameWithContent.first,
142+
FilenameWithContent.second);
143+
}
144+
137145
return Invocation.run();
138146
}
139147

0 commit comments

Comments
 (0)