Compare commits

..

369 Commits

Author SHA1 Message Date
Bill Wendling
1255f5f451 Merging r197483:
------------------------------------------------------------------------
r197483 | yrnkrn | 2013-12-17 00:40:11 -0800 (Tue, 17 Dec 2013) | 8 lines

There are no __register_frame and __deregister_frame functions 
when using structured exception handling (SEH) on Windows 64.

http://llvm-reviews.chandlerc.com/D2378

Patch by Jonathan Liu!


------------------------------------------------------------------------

llvm-svn: 197944
2013-12-24 06:50:45 +00:00
Bill Wendling
271b135a1a Small reformatting changes.
llvm-svn: 197933
2013-12-24 06:30:50 +00:00
Bill Wendling
f438c9bbf7 Small reformatting changes.
llvm-svn: 197932
2013-12-24 06:29:42 +00:00
Bill Wendling
0e1066e671 ---Merging r196453
Parse: Recover better from bad definitions with base specifiers
    
    We would skip until the next comma, hoping good things whould lie there,
    however this would fail when we have such things as this:
    
    struct A {};
    template <typename>
    struct D;
    template <>
    struct D<C> : B, A::D;
    
    Once this happens, we would believe that D with a nested namespace
    specifier of A was a variable that was being declared. We would go on
    to complain that there was an extraneous 'template <>' on their variable
    declaration.
    
    Crashes would happen when 'A' gets defined as 'enum class A {}' as
    various asserts would fire.
    
    Instead, we should skip up until the semicolon if we see that we are in
    the middle of a definition and the current token is a ':'
    
    This fixes PR17084.

llvm-svn: 197905
2013-12-23 10:02:34 +00:00
Bill Wendling
04501dbc8b Remove help notes from the ReleaseNotes.
llvm-svn: 197841
2013-12-20 22:16:21 +00:00
Bill Wendling
5fc9a797be Remove help notes from the ReleaseNotes.
llvm-svn: 197840
2013-12-20 22:14:38 +00:00
Bill Wendling
849a06ce9d Merging r197492:
------------------------------------------------------------------------
r197492 | dyatkovskiy | 2013-12-17 04:07:33 -0800 (Tue, 17 Dec 2013) | 26 lines

Fix for PR18045:
http://llvm.org/bugs/show_bug.cgi?id=18045

Short issue description:
For X86 machines with sse < sse4.1 we got failures for some
particular load/store vector sequences:

$ clang-trunk -m32 -O2 test-case.c
fatal error: error in backend: Cannot select: 0x4200920: v4i32,ch = load 0x41d6ab0, 0x4205850,
      0x41dcb10<LD16[getelementptr inbounds ([4 x i32]* @e, i32 0, i32 0)](align=4)> [ORD=82]
      [ID=58]
  0x4205850: i32 = X86ISD::Wrapper 0x41d5490 [ORD=26] [ID=43]
    0x41d5490: i32 = TargetGlobalAddress<[4 x i32]* @e> 0 [ORD=26] [ID=23]
  0x41dcb10: i32 = undef [ID=2]

The reason is that EltsFromConsecutiveLoads could emit such load instruction
both before and after legalize stage. Though this instruction is not legal for
machines with SSSE3 and lower.

The fix: In EltsFromConsecutiveLoads, if we have passed legalize stage, we
check whether nodes it emits are legal. 

P.S.: If you get failure in time from 12:00 and till 22:00 (UTC-8),
perhaps I'll slow with response, so you better reject this commit. Thanks!


------------------------------------------------------------------------

llvm-svn: 197779
2013-12-20 04:29:56 +00:00
Bill Wendling
4ed3bde672 Merging r197718:
------------------------------------------------------------------------
r197718 | hans | 2013-12-19 12:32:44 -0800 (Thu, 19 Dec 2013) | 10 lines

Make sys::ThreadLocal<> zero-initialized on non-thread builds (PR18205)

According to the docs, ThreadLocal<>::get() should return NULL
if no object has been set. This patch makes that the case also for non-thread
builds and adds a very basic unit test to check it.

(This was causing PR18205 because PrettyStackTraceHead didn't get zero-
initialized and we'd crash trying to read past the end of that list. We didn't
notice this so much on Linux since we'd crash after printing all the entries,
but on Mac we print into a SmallString, and would crash before printing that.)
------------------------------------------------------------------------

llvm-svn: 197778
2013-12-20 04:26:57 +00:00
Sylvestre Ledru
f3e44526eb Update of the release notes to provide examples of the new checks/warnings
llvm-svn: 197667
2013-12-19 10:18:31 +00:00
Bill Wendling
48b544e63c Update notes.
llvm-svn: 197468
2013-12-17 06:01:39 +00:00
Bill Wendling
e4b2a6e3e1 Merging r197409:
------------------------------------------------------------------------
r197409 | rikka | 2013-12-16 11:19:18 -0800 (Mon, 16 Dec 2013) | 4 lines

Make Sema::BuildCXXNestedNameSpecifier correctly clear the previous
CXXScopeSpec when necessary while performing typo correction. This fixes
the crash reported in PR18213 (the problem existed since r185487, and
r193020 made it easier to hit).
------------------------------------------------------------------------

llvm-svn: 197463
2013-12-17 04:29:27 +00:00
Bill Wendling
55637a32e9 Merging r197449:
------------------------------------------------------------------------
r197449 | arnolds | 2013-12-16 17:11:01 -0800 (Mon, 16 Dec 2013) | 7 lines

LoopVectorizer: Don't if-convert constant expressions that can trap

A phi node operand or an instruction operand could be a constant expression that
can trap (division). Check that we don't vectorize such cases.

PR16729
radar://15653590
------------------------------------------------------------------------

llvm-svn: 197453
2013-12-17 01:28:35 +00:00
Bill Wendling
4a062ea733 Fix link.
llvm-svn: 197443
2013-12-17 00:32:40 +00:00
Bill Wendling
dd9a13866f Add blurb about leak sanitizer.
llvm-svn: 197417
2013-12-16 19:53:36 +00:00
Sylvestre Ledru
d4ae9fdfe3 Remove a duplicate declaration which broke the compiler-rt build
llvm-svn: 197381
2013-12-16 12:27:25 +00:00
Gabor Greif
551c3277cb fix a weird phrase
llvm-svn: 197379
2013-12-16 11:18:18 +00:00
Sylvestre Ledru
b2cefb4852 Rewrite the static analyzer changes description for the 3.4 release.
After chatting with Anna Zaks, she believes that my code samples were
more bugs in the previous releases of the static analyzer.

llvm-svn: 197377
2013-12-16 10:43:55 +00:00
Sylvestre Ledru
58d24ac4d4 Add a missing declaration of Log in lldb.
Bill accepted this commit for the 3.4 release.

The build was failing with:
/tmp/buildd/llvm-toolchain-3.4-3.4~+/tools/lldb/source/Host/common/Host.cpp:1222:30: error: request for member 'Printf' in 'log', which is of non-class type 'double(double)throw ()'
log->Printf("Host::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_lldb_tmp_dir.GetCString());

llvm-svn: 197376
2013-12-16 09:49:51 +00:00
Bill Wendling
5c20ec3b92 Merging r195411:
------------------------------------------------------------------------
r195411 | mgottesman | 2013-11-21 21:00:51 -0800 (Thu, 21 Nov 2013) | 1 line

[block-freq] Update data in test case to be unsigned long long to fix mingw build.
------------------------------------------------------------------------

llvm-svn: 197363
2013-12-16 03:48:58 +00:00
Bill Wendling
0f6f2cdaae Merging r-196802:
------------------------------------------------------------------------
r196802 | chandlerc | 2013-12-09 11:25:51 -0800 (Mon, 09 Dec 2013) | 11 lines

Revert three patches which were committed without explicit contribution
by their authors.

This may break builds where others added code relying on these patches,
but please *do not* revert this commit. Instead, we will prepare patches
which fix the failures.

Reverts the following commits:
r168306: "[asan] support x32 mode in the fast stack unwinder. Patch by H.J. Lu"
r168356: "[asan] more support for powerpc, patch by Peter Bergner"
r196489: "[sanitizer] fix the ppc32 build (patch by Jakub Jelinek)"
------------------------------------------------------------------------

llvm-svn: 197360
2013-12-16 02:36:46 +00:00
Bill Wendling
a0cdb61c3e Merging r196212:
------------------------------------------------------------------------
r196212 | alp | 2013-12-02 22:13:01 -0800 (Mon, 02 Dec 2013) | 22 lines

Emit an extension warning when changing system header tokens

clang converts keywords to identifiers for compatibility with various system
headers such as GNU libc.

Implement a -Wkeyword-compat extension warning to diagnose those cases. The
warning is on by default but will generally be ignored in system headers. It
can however be enabled globally to aid standards conformance testing.

This also changes the __uptr keyword avoidance from r195710 to no longer
special-case system headers, bringing it in line with other similar workarounds
in clang.

Implementation returns bool for symmetry with token annotation functions.

Some examples:

warning: keyword '__is_pod' will be treated as an identifier for the remainder of the translation unit [-Wkeyword-compat]
struct __is_pod

warning: keyword '__uptr' will be treated as an identifier here [-Wkeyword-compat]
union w *__uptr;
------------------------------------------------------------------------

llvm-svn: 197359
2013-12-16 02:32:55 +00:00
Bill Wendling
0637cda9f6 Merging r197047:
------------------------------------------------------------------------
r197047 | d0k | 2013-12-11 08:36:09 -0800 (Wed, 11 Dec 2013) | 3 lines

SelectionDAG: Fix a typo.

Found by "cppcheck". PR18208.
------------------------------------------------------------------------

llvm-svn: 197355
2013-12-15 21:02:34 +00:00
Bill Wendling
fe81660c55 Merging r195710:
------------------------------------------------------------------------

llvm-svn: 197354
2013-12-15 20:58:02 +00:00
Bill Wendling
9cae954623 Merging r196779:
------------------------------------------------------------------------
r196779 | samsonov | 2013-12-09 05:21:43 -0800 (Mon, 09 Dec 2013) | 11 lines

PR17977: don't assume EOWNERDEAD is always defined

Summary: See details in http://llvm.org/bugs/show_bug.cgi?id=17977

Reviewers: dvyukov

Reviewed By: dvyukov

CC: glider, llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D2340
------------------------------------------------------------------------

llvm-svn: 197353
2013-12-15 20:56:43 +00:00
Bill Wendling
411ef18589 Merging r197216:
------------------------------------------------------------------------
r197216 | chandlerc | 2013-12-13 00:00:01 -0800 (Fri, 13 Dec 2013) | 9 lines

[inliner] Fix PR18206 by preventing inlining functions that call setjmp
through an invoke instruction.

The original patch for this was written by Mark Seaborn, but I've
reworked his test case into the existing returns_twice test case and
implemented the fix by the prior refactoring to actually run the cost
analysis over invoke instructions, and then here fixing our detection of
the returns_twice attribute to work for both calls and invokes. We never
noticed because we never saw an invoke. =[
------------------------------------------------------------------------

llvm-svn: 197352
2013-12-15 20:55:09 +00:00
Bill Wendling
4e547a68f8 Merging r197215:
------------------------------------------------------------------------
r197215 | chandlerc | 2013-12-12 23:59:56 -0800 (Thu, 12 Dec 2013) | 24 lines

[inliner] Completely change (and fix) how the inline cost analysis
handles terminator instructions.

The inline cost analysis inheritted some pretty rough handling of
terminator insts from the original cost analysis, and then made it much,
much worse by factoring all of the important analyses into a separate
instruction visitor. That instruction visitor never visited the
terminator.

This works fine for things like conditional branches, but for many other
things we simply computed The Wrong Value. First example are
unconditional branches, which should be free but were counted as full
cost. This is most significant for conditional branches where the
condition simplifies and folds during inlining. We paid a 1 instruction
tax on every branch in a straight line specialized path. =[

Oh, we also claimed that the unreachable instruction had cost.

But it gets worse. Let's consider invoke. We never applied the call
penalty. We never accounted for the cost of the arguments. Nope. Worse
still, we didn't handle the *correctness* constraints of not inlining
recursive invokes, or exception throwing returns_twice functions. Oops.
See PR18206. Sadly, PR18206 requires yet another fix, but this
refactoring is at least a huge step in that direction.
------------------------------------------------------------------------

llvm-svn: 197351
2013-12-15 20:54:53 +00:00
Hal Finkel
8817229b97 Add release notes for the PowerPC backend
llvm-svn: 197325
2013-12-14 14:41:55 +00:00
Bill Wendling
1c2dbf2d3b Merging r197178:
------------------------------------------------------------------------
r197178 | hfinkel | 2013-12-12 12:45:24 -0800 (Thu, 12 Dec 2013) | 9 lines

Fix a use-after-free error in GlobalOpt CleanupConstantGlobalUsers

GlobalOpt's CleanupConstantGlobalUsers function uses a worklist array to manage
constant users to be visited. The pointers in this array need to be weak
handles because when we delete a constant array, we may also be holding a
pointer to one of its elements (or an element of one of its elements if we're
dealing with an array of arrays) in the worklist.

Fixes PR17347.
------------------------------------------------------------------------

llvm-svn: 197322
2013-12-14 08:04:09 +00:00
Bill Wendling
041b14f92c Merging r197228:
------------------------------------------------------------------------
r197228 | d0k | 2013-12-13 05:40:24 -0800 (Fri, 13 Dec 2013) | 8 lines

X86: When lowering shl_parts, don't emit shift amounts larger than the bit width.

While it's safe for the X86-specific shift nodes, dag combining will
kill generic nodes. Insert an AND to make it safe, isel will nuke it
as x86's shift instructions have an implicit AND.

Fixes PR16108, which contains a contraption to hit this case in between
constant folders.
------------------------------------------------------------------------

llvm-svn: 197321
2013-12-14 08:01:30 +00:00
Bill Wendling
c710da2426 Merging r197298:
------------------------------------------------------------------------
r197298 | rsmith | 2013-12-13 17:04:22 -0800 (Fri, 13 Dec 2013) | 3 lines

PR18232: implement instantiation for class-scope explicit specializations of
class templates (a Microsoft extension).

------------------------------------------------------------------------

llvm-svn: 197320
2013-12-14 07:59:40 +00:00
Bill Wendling
8f456a6ce4 Merging r197305:
------------------------------------------------------------------------
r197305 | rsmith | 2013-12-13 19:18:05 -0800 (Fri, 13 Dec 2013) | 7 lines

PR18246: When performing template argument deduction to decide which template
is specialized by an explicit specialization, start from the first declaration
in case we've got a member of a class template (redeclarations might not number
the template parameters the same way).

Our recover here is still far from ideal.

------------------------------------------------------------------------

llvm-svn: 197319
2013-12-14 07:59:17 +00:00
Sylvestre Ledru
562069800c Improve the 3.4 release notes about the static analyzer new features
llvm-svn: 197225
2013-12-13 11:30:23 +00:00
Bill Wendling
09c8c8835c Fix URL.
llvm-svn: 197203
2013-12-13 04:19:05 +00:00
Bill Wendling
bceb7a621c Merging r197061:
------------------------------------------------------------------------
r197061 | marshall | 2013-12-11 11:32:32 -0800 (Wed, 11 Dec 2013) | 1 line

Move std::begin(array) and std::end(array) out from under an #ifdef that was preventing people from building libc++ using gcc. This corrects a mistake that I introduced in r196058
------------------------------------------------------------------------

llvm-svn: 197134
2013-12-12 07:07:15 +00:00
Bill Wendling
9fb5fc9684 Merging r196058:
------------------------------------------------------------------------
r196058 | marshall | 2013-12-01 19:24:33 -0800 (Sun, 01 Dec 2013) | 1 line

Fix for PRPR17934; based on a fix suggested by Peter Sommerlad
------------------------------------------------------------------------

llvm-svn: 197133
2013-12-12 07:06:59 +00:00
Bill Wendling
26d28e51b8 Merging r-197100:
------------------------------------------------------------------------
r197100 | hfinkel | 2013-12-11 16:23:29 -0800 (Wed, 11 Dec 2013) | 1 line

Remove unused multiclass from PPCInstrInfo.td
------------------------------------------------------------------------

llvm-svn: 197131
2013-12-12 06:44:57 +00:00
Bill Wendling
87298e5124 Merging r197100:
------------------------------------------------------------------------
r197100 | hfinkel | 2013-12-11 16:23:29 -0800 (Wed, 11 Dec 2013) | 1 line

Remove unused multiclass from PPCInstrInfo.td
------------------------------------------------------------------------

llvm-svn: 197130
2013-12-12 06:42:41 +00:00
Bill Wendling
317f672d96 Merging r197120:
------------------------------------------------------------------------
r197120 | rsmith | 2013-12-11 18:42:17 -0800 (Wed, 11 Dec 2013) | 2 lines

Update user manual to note that implementation for C++11 and C++1y is complete, and fix a bunch of other issues here.

------------------------------------------------------------------------

llvm-svn: 197127
2013-12-12 04:30:51 +00:00
Bill Wendling
d92b12df0f Merging r197089:
------------------------------------------------------------------------
r197089 | hfinkel | 2013-12-11 15:12:25 -0800 (Wed, 11 Dec 2013) | 6 lines

Fix the PPC subsumes-predicate check

For one predicate to subsume another, they must both check the same condition
register. Failure to check this prerequisite was causing miscompiles.

Fixes PR18003.
------------------------------------------------------------------------

llvm-svn: 197126
2013-12-12 04:28:52 +00:00
Richard Smith
82930e7019 Fix another formatting bug.
llvm-svn: 197118
2013-12-12 02:30:46 +00:00
Richard Smith
f0bbdf608e Fix RST syntax errors.
llvm-svn: 197117
2013-12-12 02:26:06 +00:00
Richard Smith
ef105998a6 Add information about C++1y support to Clang 3.4 release notes.
llvm-svn: 197115
2013-12-12 02:20:54 +00:00
Daniel Jasper
bd1c1c7832 Add release notes for clang-format.
llvm-svn: 197042
2013-12-11 14:41:33 +00:00
Sergey Matveev
f4312bf40e Merging r197022:
------------------------------------------------------------------------
r197022 | smatveev | 2013-12-11 13:14:36 +0400 (Wed, 11 Dec 2013) | 1 line

Mention LeakSanitizer in AddressSanitizer docs.
------------------------------------------------------------------------

llvm-svn: 197023
2013-12-11 09:15:45 +00:00
Bill Wendling
80ca990f60 Merging r-196058:
------------------------------------------------------------------------
r196058 | marshall | 2013-12-01 19:24:33 -0800 (Sun, 01 Dec 2013) | 1 line

Fix for PRPR17934; based on a fix suggested by Peter Sommerlad
------------------------------------------------------------------------

llvm-svn: 197013
2013-12-11 07:25:36 +00:00
Bill Wendling
45d1e2276f Readd the prototype.
llvm-svn: 197012
2013-12-11 06:28:27 +00:00
Bill Wendling
9504f945c3 Merging r196802:
------------------------------------------------------------------------
r196802 | chandlerc | 2013-12-09 11:25:51 -0800 (Mon, 09 Dec 2013) | 11 lines

Revert three patches which were committed without explicit contribution
by their authors.

This may break builds where others added code relying on these patches,
but please *do not* revert this commit. Instead, we will prepare patches
which fix the failures.

Reverts the following commits:
r168306: "[asan] support x32 mode in the fast stack unwinder. Patch by H.J. Lu"
r168356: "[asan] more support for powerpc, patch by Peter Bergner"
r196489: "[sanitizer] fix the ppc32 build (patch by Jakub Jelinek)"
------------------------------------------------------------------------

llvm-svn: 197011
2013-12-11 06:24:52 +00:00
Bill Wendling
dd45e0c9d3 Merging r196809:
------------------------------------------------------------------------
r196809 | rsmith | 2013-12-09 11:52:39 -0800 (Mon, 09 Dec 2013) | 2 lines

Unbreak build by adding an implementation of PopStackFrames function.

------------------------------------------------------------------------

llvm-svn: 197010
2013-12-11 06:14:02 +00:00
Bill Wendling
d99c9122e4 Merging r196995:
------------------------------------------------------------------------
r196995 | rsmith | 2013-12-10 17:40:16 -0800 (Tue, 10 Dec 2013) | 5 lines

When performing an array new of a multidimensional array with an initializer
list, each element of the initializer list may provide more than one of the
base elements of the array. Be sure to initialize the right type and bump the
array pointer by the right amount.

------------------------------------------------------------------------

llvm-svn: 197005
2013-12-11 04:25:35 +00:00
Bill Wendling
522cb01c66 Add LibBeauty blurb.
llvm-svn: 197004
2013-12-11 04:18:46 +00:00
Sergey Matveev
c2d12295c3 Merging r196957:
------------------------------------------------------------------------
r196957 | smatveev | 2013-12-11 00:10:30 +0400 (Wed, 11 Dec 2013) | 1 line

Rewrite docs/LeakSanitizer.rst. Add it to index.
------------------------------------------------------------------------

llvm-svn: 196958
2013-12-10 20:13:58 +00:00
Bill Wendling
1af8ed5ed9 Merging r196768:
------------------------------------------------------------------------
r196768 | majnemer | 2013-12-09 01:04:00 -0800 (Mon, 09 Dec 2013) | 5 lines

ADT: Implement MutableArrayRef::reverse_iterator

This adds rbegin/rend methods to MutableArrayRef, they will be used by a
follow-on commit in clang.

------------------------------------------------------------------------

llvm-svn: 196945
2013-12-10 18:46:12 +00:00
Bill Wendling
208ece8012 Merging r196858:
------------------------------------------------------------------------
r196858 | nadav | 2013-12-09 17:13:59 -0800 (Mon, 09 Dec 2013) | 1 line

Fix PR18162 - Incorrect assertion assumed that the SDValue resno is zero.
------------------------------------------------------------------------

llvm-svn: 196886
2013-12-10 06:42:24 +00:00
Bill Wendling
d0c09393d0 Merging r196852:
------------------------------------------------------------------------
r196852 | majnemer | 2013-12-09 16:40:58 -0800 (Mon, 09 Dec 2013) | 10 lines

Sema: Enforce C++11 pointer-to-member template arguments should rules

The standard is pretty clear on what it allows inside of template
arguments for non-type template parameters of pointer-to-member.

They must be of the form &qualified-id and cannot come from sources like
constexpr VarDecls or things of that nature.

This fixes PR18192.

------------------------------------------------------------------------

llvm-svn: 196885
2013-12-10 06:41:28 +00:00
Bill Wendling
bfe648303a Merging r196771:
------------------------------------------------------------------------
r196771 | majnemer | 2013-12-09 02:44:32 -0800 (Mon, 09 Dec 2013) | 17 lines

[-cxx-abi microsoft] Mangle large integral constants correctly

Testing has revealed that large integral constants (i.e. > INT64_MAX)
are always mangled as-if they are negative, even in places where it
would not make sense for them to be negative (like non-type template
parameters of type unsigned long long).

To address this, we change the way we model number mangling: always
mangle as-if our number is an int64_t.  This should result in correct
results when we have large unsigned numbers.

N.B.  Bizarrely, things that are 32-bit displacements like vbptr offsets
are mangled as-if they are unsigned 32-bit numbers.  This is a pretty
egregious waste of space, it would be a 4x savings if we could mangle it
like a signed 32-bit number.  Instead, we explicitly cast these
displacements to uint32_t and let the mangler proceed.

------------------------------------------------------------------------

llvm-svn: 196878
2013-12-10 05:29:38 +00:00
Bill Wendling
24c618e110 Merging r196806:
------------------------------------------------------------------------
r196806 | apazos | 2013-12-09 11:29:14 -0800 (Mon, 09 Dec 2013) | 11 lines


Fix pattern match for movi with 0D result

Patch by Jiangning Liu.

With some test case changes:
- intrinsic test added to the existing /test/CodeGen/AArch64/neon-aba-abd.ll.
- New test cases to cover movi 1D scenario without using the intrinsic in
test/CodeGen/AArch64/neon-mov.ll.


------------------------------------------------------------------------

llvm-svn: 196872
2013-12-10 04:31:42 +00:00
Bill Wendling
00309d5b3d Merging r196799:
------------------------------------------------------------------------
r196799 | wdietz2 | 2013-12-09 11:04:33 -0800 (Mon, 09 Dec 2013) | 1 line

ubsan: Fix typo in 'TypeCheck/vptr.cpp' test to resolve 32bit failure.
------------------------------------------------------------------------

llvm-svn: 196871
2013-12-10 04:30:36 +00:00
Bill Wendling
f93783c49b Merging r196612:
------------------------------------------------------------------------
r196612 | wdietz2 | 2013-12-06 13:49:18 -0800 (Fri, 06 Dec 2013) | 1 line

Fix integer tests on platforms where uint64_t is 'unsigned long long'.
------------------------------------------------------------------------

llvm-svn: 196870
2013-12-10 04:30:17 +00:00
Bill Wendling
dcfc9c32df Merging r196612:
------------------------------------------------------------------------

llvm-svn: 196869
2013-12-10 04:29:40 +00:00
Bill Wendling
ebfc8a59c6 Merging r196612:
------------------------------------------------------------------------

llvm-svn: 196868
2013-12-10 04:29:17 +00:00
Manman Ren
48650e8a58 Merging r196172:
------------------------------------------------------------------------
r196172 | mren | 2013-12-02 16:12:14 -0800 (Mon, 02 Dec 2013) | 4 lines

Debug Info: rename getDebugInfoVersionFromModule to getDebugMetadataVersionFromModule.

Suggested by Eric.

------------------------------------------------------------------------

llvm-svn: 196823
2013-12-09 21:07:27 +00:00
Manman Ren
6d31451246 Merging r196158:
------------------------------------------------------------------------
r196158 | mren | 2013-12-02 13:29:56 -0800 (Mon, 02 Dec 2013) | 12 lines

Debug Info: drop debug info via upgrading path if version number does not match.

Add a helper function getDebugInfoVersionFromModule to return the debug info
version number for a module.

"Verifier/module-flags-1.ll" checks for verification errors.
It will seg fault when calling getDebugInfoVersionFromModule because of the
incorrect format for module flags in the testing case. We make
getModuleFlagsMetadata more robust by checking for error conditions.

PR17982

------------------------------------------------------------------------

llvm-svn: 196822
2013-12-09 21:06:30 +00:00
Manman Ren
2d78d90111 Merging r196156:
------------------------------------------------------------------------
r196156 | mren | 2013-12-02 13:25:56 -0800 (Mon, 02 Dec 2013) | 2 lines

Update Ocaml/vmcore.ml to emit a "Debug Info Version" module flag.

------------------------------------------------------------------------

llvm-svn: 196821
2013-12-09 21:05:36 +00:00
Manman Ren
2bb4be6504 Merging r196145:
------------------------------------------------------------------------
r196145 | mren | 2013-12-02 12:10:37 -0800 (Mon, 02 Dec 2013) | 5 lines

Debug Info: Move the constant for Debug Info Version from Dwarf.h to Metadata.h.

Suggested by Eric.
Paired commit with r196144.

------------------------------------------------------------------------

llvm-svn: 196820
2013-12-09 21:04:35 +00:00
Manman Ren
4f9577b957 Merging r196144:
------------------------------------------------------------------------
r196144 | mren | 2013-12-02 12:09:52 -0800 (Mon, 02 Dec 2013) | 4 lines

Debug Info: Move the constant for Debug Info Version from Dwarf.h to Metadata.h.

Suggested by Eric.

------------------------------------------------------------------------

llvm-svn: 196819
2013-12-09 21:03:35 +00:00
Manman Ren
3c51e556d2 Merging r196143:
------------------------------------------------------------------------
r196143 | mren | 2013-12-02 11:37:35 -0800 (Mon, 02 Dec 2013) | 1 line

Expand comments for Debug Info Version.
------------------------------------------------------------------------

llvm-svn: 196818
2013-12-09 21:02:26 +00:00
Manman Ren
cabc39a6e6 Merging r195535:
------------------------------------------------------------------------
r195535 | mren | 2013-11-22 17:16:29 -0800 (Fri, 22 Nov 2013) | 8 lines

Debug Info: update testing cases to specify the debug info version number.

We are going to drop debug info without a version number or with a different
version number, to make sure we don't crash when we see bitcode files with
different debug info metadata format.

Make tests more robust by removing hard-coded metadata numbers in CHECK lines.

------------------------------------------------------------------------

llvm-svn: 196817
2013-12-09 21:01:06 +00:00
Manman Ren
f685fdd3b1 Merging r195505:
------------------------------------------------------------------------
r195505 | mren | 2013-11-22 14:06:31 -0800 (Fri, 22 Nov 2013) | 8 lines

Debug Info: move StripDebugInfo from StripSymbols.cpp to DebugInfo.cpp.

We can share the implementation between StripSymbols and dropping debug info
for metadata versions that do not match.

Also update the comments to match the implementation. A follow-on patch will
drop the "Debug Info Version" module flag in StripDebugInfo.

------------------------------------------------------------------------

llvm-svn: 196816
2013-12-09 21:00:02 +00:00
Manman Ren
d52ef95fee Merging r195504:
------------------------------------------------------------------------
r195504 | mren | 2013-11-22 13:49:45 -0800 (Fri, 22 Nov 2013) | 6 lines

Debug Info: update testing cases to specify the debug info version number.

We are going to drop debug info without a version number or with a different
version number, to make sure we don't crash when we see bitcode files with
different debug info metadata format.

------------------------------------------------------------------------

llvm-svn: 196815
2013-12-09 20:58:24 +00:00
Manman Ren
cf8001e35f Merging r195495:
------------------------------------------------------------------------
r195495 | mren | 2013-11-22 11:42:45 -0800 (Fri, 22 Nov 2013) | 5 lines

Debug Info: add a "Debug Info Version" module flag to output the current debug
info version number.

Will error out when modules have different version numbers.

------------------------------------------------------------------------

llvm-svn: 196812
2013-12-09 20:27:01 +00:00
Hans Wennborg
791aeab970 Release notes: expand clang-cl blurb a little
llvm-svn: 196810
2013-12-09 20:00:25 +00:00
Bill Wendling
4141aeeb71 Merging r196599:
------------------------------------------------------------------------
r196599 | zaks | 2013-12-06 11:28:16 -0800 (Fri, 06 Dec 2013) | 5 lines

Fixup to r196593.

This is another regression fixed by reverting r189090.

In this case, the problem is not live variables but the approach that was taken in r189090. This regression was caused by explicitly binding "true" to the condition when we take the true branch. Normally that's okay, but in this case we're planning to reuse that condition as the value of the expression.
------------------------------------------------------------------------

llvm-svn: 196796
2013-12-09 18:37:20 +00:00
Bill Wendling
6e477ccc5f Merging r196593:
------------------------------------------------------------------------
r196593 | zaks | 2013-12-06 10:56:29 -0800 (Fri, 06 Dec 2013) | 7 lines

Revert "[analyzer] Refactor conditional expression evaluating code"

This reverts commit r189090.

The original patch introduced regressions (see the added live-variables.* tests). The patch depends on the correctness of live variable analyses, which are not computed correctly. I've opened PR18159 to track the proper resolution to this problem.

The patch was a stepping block to r189746. This is why part of the patch reverts temporary destructor tests that started crashing. The temporary destructors feature is disabled by default.
------------------------------------------------------------------------

llvm-svn: 196795
2013-12-09 18:37:00 +00:00
Tim Northover
347dfb0dac Remove stray parts of (reverted on trunk) r196205 that are causing test
failures.

llvm-svn: 196774
2013-12-09 11:21:49 +00:00
Tim Northover
f10640abf2 Merge rest of r196210. Some bits strayed into r196701, turning 3.4 red. This
should fix the issue.
------------------------------------------------------------------------
r196210 | haoliu | 2013-12-03 06:06:55 +0000 (Tue, 03 Dec 2013) | 3 lines

[AArch64]Add missing floating point convert, round and misc intrinsics.
E.g. int64x1_t vcvt_s64_f64(float64x1_t a) -> FCVTZS Dd, Dn

------------------------------------------------------------------------

llvm-svn: 196772
2013-12-09 10:48:32 +00:00
Tim Northover
21940adcf2 Merge r196725 (conflicts on same API as before):
------------------------------------------------------------------------
r196725 | tnorthover | 2013-12-08 15:56:50 +0000 (Sun, 08 Dec 2013) |
19 lines

ARM: fix folding of stack-adjustment (yet again).

When trying to eliminate an "sub sp, sp, #N" instruction by folding
it into an existing push/pop using dummy registers, we need to account
for the fact that this might affect precisely how "fp" gets set in the
prologue.

We were attempting this, but assuming that *whenever* we performed a
fold it would make a difference. This is false, for example, in:
    push {r4, r7, lr}
    add fp, sp, #4
    vpush {d8}
    sub sp, sp, #8

we can fold the "sub" into the "vpush", forming "vpush {d7, d8}".
However, in that case the "add fp" instruction mustn't change, which
we were getting wrong before.

Should fix PR18160.
------------------------------------------------------------------------

llvm-svn: 196769
2013-12-09 09:05:30 +00:00
Bill Wendling
d609e0d30f Merging r196751:
------------------------------------------------------------------------
r196751 | venkatra | 2013-12-08 20:02:15 -0800 (Sun, 08 Dec 2013) | 3 lines

[Sparc]: Implement getSetCCResultType() in SparcTargetLowering so that umulo/smulo can be lowered on sparcv9 without an assertion error.


------------------------------------------------------------------------

llvm-svn: 196766
2013-12-09 08:56:18 +00:00
Bill Wendling
db9bc0c41f Merging r196755:
------------------------------------------------------------------------
r196755 | venkatra | 2013-12-08 21:13:25 -0800 (Sun, 08 Dec 2013) | 2 lines

[SPARCV9]: Adjust the resultant pointer of DYNAMIC_STACKALLOC with the stack BIAS on sparcV9.

------------------------------------------------------------------------

llvm-svn: 196764
2013-12-09 08:55:55 +00:00
Bill Wendling
ef83bc1290 Merging r195495:
------------------------------------------------------------------------

llvm-svn: 196761
2013-12-09 08:36:26 +00:00
Bill Wendling
6e94aeb715 Merging r195494:
------------------------------------------------------------------------
r195494 | mren | 2013-11-22 11:41:59 -0800 (Fri, 22 Nov 2013) | 4 lines

Debug Info: add a constant for debug info version number.

This will be used to output the debug info version number as a module flag.

------------------------------------------------------------------------

llvm-svn: 196760
2013-12-09 08:35:51 +00:00
Bill Wendling
2096ac3d50 Merging r196720:
------------------------------------------------------------------------
r196720 | joerg | 2013-12-08 05:54:58 -0800 (Sun, 08 Dec 2013) | 3 lines

Extend assembler handling for NetBSD/MIPS to pass down the correct ABI,
architecture and PIC flag.

------------------------------------------------------------------------

llvm-svn: 196747
2013-12-09 02:59:27 +00:00
Bill Wendling
b775123c97 Merging r196724:
------------------------------------------------------------------------
r196724 | tnorthover | 2013-12-08 07:24:55 -0800 (Sun, 08 Dec 2013) | 5 lines

ARM: teach Sema that "r" can match 64-bit values

We already support using "r" on 64-bit values (a GPRPair is
allocated), but Sema doesn't know this yet so issues a warning. This
should fix it.
------------------------------------------------------------------------

llvm-svn: 196746
2013-12-09 02:58:56 +00:00
Bill Wendling
bafdcc655d Merging r196712:
------------------------------------------------------------------------
r196712 | rafael | 2013-12-07 17:13:22 -0800 (Sat, 07 Dec 2013) | 12 lines

Fix pr18174.

Clang outputs LLVM one top level decl at a time. This combined with the
visibility computation code looking for the newest NamespaceDecl would cause
it to produce different results for nested namespaces.

The two options for producing consistent results are
* Delay codegen of anything inside a namespace until the end of the file.
* Don't look for the newest NamespaceDecl.

This patch implements the second option.
This matches the gcc behavior too.
------------------------------------------------------------------------

llvm-svn: 196745
2013-12-09 02:00:10 +00:00
Bill Wendling
7f06b27990 Merging r196735:
------------------------------------------------------------------------
r196735 | venkatra | 2013-12-08 14:06:07 -0800 (Sun, 08 Dec 2013) | 3 lines

[SparcV9]: Expand MULHU/MULHS:i64 and UMUL_LOHI/SMUL_LOHI:i64 on sparcv9.
  This fixes PR18150.

------------------------------------------------------------------------

llvm-svn: 196744
2013-12-09 01:54:36 +00:00
Tim Northover
9175124f5c Merging r196493. Simple conflict due to change API of updated
function.

llvm-svn: 196717
2013-12-08 08:12:20 +00:00
Bill Wendling
8199a2ac76 Merging r196638:
------------------------------------------------------------------------
r196638 | arsenm | 2013-12-06 18:58:45 -0800 (Fri, 06 Dec 2013) | 1 line

Fix assert with copy from global through addrspacecast
------------------------------------------------------------------------

llvm-svn: 196709
2013-12-08 00:25:40 +00:00
Bill Wendling
914cc74657 Merging r196668:
------------------------------------------------------------------------

llvm-svn: 196708
2013-12-08 00:25:14 +00:00
Bill Wendling
4707660286 Merging r196637:
------------------------------------------------------------------------
r196637 | arsenm | 2013-12-06 18:58:41 -0800 (Fri, 06 Dec 2013) | 1 line

Add getBitCastOrAddrSpaceCast
------------------------------------------------------------------------

llvm-svn: 196707
2013-12-08 00:23:35 +00:00
Bill Wendling
6caa88f95f Merging r196630:
------------------------------------------------------------------------
r196630 | joerg | 2013-12-06 16:57:46 -0800 (Fri, 06 Dec 2013) | 3 lines

Pass correct flags to assembler and linker for OpenBSD on AMD64, PowerPC
and MIPS64. From Brad Smith.

------------------------------------------------------------------------

llvm-svn: 196706
2013-12-08 00:21:01 +00:00
Bill Wendling
2b283eb812 --- Reverse-merging r196668 into '.':
U    lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
U    test/Transforms/InstCombine/addrspacecast.ll

llvm-svn: 196705
2013-12-08 00:19:49 +00:00
Bill Wendling
919680ef34 Merging r196588:
------------------------------------------------------------------------
r196588 | weimingz | 2013-12-06 09:56:48 -0800 (Fri, 06 Dec 2013) | 7 lines

Bug 18149: [AArch32] VSel instructions has no ARMCC field

The current peephole optimizing for compare inst assumes an instr that
uses CPSR has an MO for ARM Cond code.However, for VSEL instructions
(vseqeq, vselgt, vselgt, vselvs), there is no such operand nor do
they support the modification of Cond Code.

------------------------------------------------------------------------

llvm-svn: 196704
2013-12-08 00:17:29 +00:00
Bill Wendling
7083c045ed Merging r196588:
------------------------------------------------------------------------

llvm-svn: 196703
2013-12-08 00:17:11 +00:00
Bill Wendling
28f6ae39e4 Merging r196535:
------------------------------------------------------------------------

llvm-svn: 196702
2013-12-08 00:08:32 +00:00
Bill Wendling
0ca0763e7e Merging r196533:
------------------------------------------------------------------------
r196533 | apazos | 2013-12-05 13:07:49 -0800 (Thu, 05 Dec 2013) | 3 lines

Implemented vget/vset_lane_f16 intrinsics


------------------------------------------------------------------------

llvm-svn: 196701
2013-12-08 00:08:20 +00:00
Bill Wendling
9897ba1993 Merging r196456:
------------------------------------------------------------------------
r196456 | jiangning | 2013-12-04 18:12:01 -0800 (Wed, 04 Dec 2013) | 2 lines

For AArch64, add missing register cost calculation for big value types like v4i64 and v8i64.

------------------------------------------------------------------------

llvm-svn: 196700
2013-12-08 00:07:48 +00:00
Bill Wendling
bb3f9f032a Merging r196362:
------------------------------------------------------------------------
r196362 | kevinqin | 2013-12-04 00:02:34 -0800 (Wed, 04 Dec 2013) | 1 line

[AArch64 Neon] Add ACLE intrinsic vceqz_f64.
------------------------------------------------------------------------

llvm-svn: 196699
2013-12-08 00:07:30 +00:00
Bill Wendling
e94e7baa09 Merging r196361:
------------------------------------------------------------------------

llvm-svn: 196698
2013-12-08 00:07:14 +00:00
Bill Wendling
2946349792 Merging r196360:
------------------------------------------------------------------------
r196360 | kevinqin | 2013-12-03 23:53:28 -0800 (Tue, 03 Dec 2013) | 1 line

[AArch64 NEON] Add missing compare intrinsics.
------------------------------------------------------------------------

llvm-svn: 196697
2013-12-08 00:07:01 +00:00
Bill Wendling
19fca91c97 Merging r196359:
------------------------------------------------------------------------

llvm-svn: 196696
2013-12-08 00:06:43 +00:00
Bill Wendling
7e5a55deb0 Merging r196211:
------------------------------------------------------------------------

llvm-svn: 196695
2013-12-08 00:06:30 +00:00
Bill Wendling
b387dbe15f Merging r196209:
------------------------------------------------------------------------

llvm-svn: 196694
2013-12-08 00:06:17 +00:00
Bill Wendling
1ae87e9c42 Merging r196208:
------------------------------------------------------------------------
r196208 | haoliu | 2013-12-02 21:58:30 -0800 (Mon, 02 Dec 2013) | 3 lines

AArch64: add missing ACLE intrinsics mapping to general arithmetic operation from VFP instructions.
E.g. float64x1_t vadd_f64(float64x1_t a, float64x1_t b) -> FADD Dd, Dn, Dm.

------------------------------------------------------------------------

llvm-svn: 196693
2013-12-08 00:06:05 +00:00
Bill Wendling
b9202097fc Merging r196199:
------------------------------------------------------------------------

llvm-svn: 196692
2013-12-08 00:05:49 +00:00
Bill Wendling
bdf680c262 Merging r196198:
------------------------------------------------------------------------
r196198 | haoliu | 2013-12-02 19:39:47 -0800 (Mon, 02 Dec 2013) | 3 lines

AArch64: Add missing scalar pair intrinsics.
E.g. "float32_t vaddv_f32(float32x2_t a)" to be matched into "faddp s0, v1.2s".

------------------------------------------------------------------------

llvm-svn: 196691
2013-12-08 00:05:35 +00:00
Bill Wendling
8bd2b93930 Merging r196192:
------------------------------------------------------------------------
r196192 | jiangning | 2013-12-02 17:33:52 -0800 (Mon, 02 Dec 2013) | 2 lines

Add some missing pattern matches for AArch64 Neon intrinsics like vuqadd_s64 and friends.

------------------------------------------------------------------------

llvm-svn: 196690
2013-12-08 00:05:18 +00:00
Bill Wendling
982ffcdf80 Merging r196191:
------------------------------------------------------------------------

llvm-svn: 196689
2013-12-08 00:05:00 +00:00
Bill Wendling
7de3d98871 Merging r196190:
------------------------------------------------------------------------
r196190 | jiangning | 2013-12-02 17:29:32 -0800 (Mon, 02 Dec 2013) | 2 lines

Add some missing pattern matches for AArch64 Neon intrinsics like vmull_high_n_s16 and friends.

------------------------------------------------------------------------

llvm-svn: 196688
2013-12-08 00:04:47 +00:00
Bill Wendling
03ea922c3c Merging r196189:
------------------------------------------------------------------------

llvm-svn: 196687
2013-12-08 00:04:29 +00:00
Bill Wendling
1da2736eb3 Merging r196535:
------------------------------------------------------------------------
r196535 | apazos | 2013-12-05 13:13:24 -0800 (Thu, 05 Dec 2013) | 1 line

Implemented vget/vset_lane_f16 intrinsics
------------------------------------------------------------------------

llvm-svn: 196686
2013-12-08 00:04:11 +00:00
Bill Wendling
b1dd04df74 Merging r196533:
------------------------------------------------------------------------

llvm-svn: 196685
2013-12-08 00:03:53 +00:00
Bill Wendling
32972d6e52 Merging r196456:
------------------------------------------------------------------------

llvm-svn: 196684
2013-12-08 00:03:41 +00:00
Bill Wendling
0d913c25b2 Merging r196362:
------------------------------------------------------------------------

llvm-svn: 196683
2013-12-08 00:03:29 +00:00
Bill Wendling
77a9fe6acf Merging r196361:
------------------------------------------------------------------------
r196361 | kevinqin | 2013-12-04 00:02:11 -0800 (Wed, 04 Dec 2013) | 1 line

[AArch64 NEON] Add ACLE intrinsic vceqz_f64.
------------------------------------------------------------------------

llvm-svn: 196682
2013-12-08 00:03:17 +00:00
Bill Wendling
afaeca5895 Merging r196360:
------------------------------------------------------------------------

llvm-svn: 196681
2013-12-08 00:03:01 +00:00
Bill Wendling
e9282cfc68 Merging r196359:
------------------------------------------------------------------------
r196359 | kevinqin | 2013-12-03 23:53:09 -0800 (Tue, 03 Dec 2013) | 1 line

[AArch64 NEON] Add missing compare intrinsics.
------------------------------------------------------------------------

llvm-svn: 196680
2013-12-08 00:02:49 +00:00
Bill Wendling
ff61b86416 Merging r196211:
------------------------------------------------------------------------
r196211 | haoliu | 2013-12-02 22:07:13 -0800 (Mon, 02 Dec 2013) | 3 lines

[AArch64]Add missing floating point convert, round and misc intrinsics.
E.g. int64x1_t vcvt_s64_f64(float64x1_t a) -> FCVTZS Dd, Dn

------------------------------------------------------------------------

llvm-svn: 196679
2013-12-08 00:02:31 +00:00
Bill Wendling
5618a85f56 Merging r196209:
------------------------------------------------------------------------
r196209 | haoliu | 2013-12-02 21:58:49 -0800 (Mon, 02 Dec 2013) | 3 lines

AArch64: add missing ACLE intrinsics mapping to general arithmetic operation from VFP instructions.
E.g. float64x1_t vadd_f64(float64x1_t a, float64x1_t b) -> FADD Dd, Dn, Dm.

------------------------------------------------------------------------

llvm-svn: 196678
2013-12-08 00:02:12 +00:00
Bill Wendling
f4b78a1e78 Merging r196208:
------------------------------------------------------------------------

llvm-svn: 196677
2013-12-08 00:01:55 +00:00
Bill Wendling
fddc9d1f53 Merging r196199:
------------------------------------------------------------------------
r196199 | haoliu | 2013-12-02 19:40:08 -0800 (Mon, 02 Dec 2013) | 3 lines

AArch64: Add missing scalar pair intrinsics.
E.g. "float32_t vaddv_f32(float32x2_t a)" to be matched into "faddp s0, v1.2s".

------------------------------------------------------------------------

llvm-svn: 196676
2013-12-08 00:01:42 +00:00
Bill Wendling
8a5ca09d73 Merging r196198:
------------------------------------------------------------------------

llvm-svn: 196675
2013-12-08 00:01:25 +00:00
Bill Wendling
64c9f2f868 Merging r196192:
------------------------------------------------------------------------

llvm-svn: 196674
2013-12-08 00:01:12 +00:00
Bill Wendling
9020e09fd5 Merging r196191:
------------------------------------------------------------------------
r196191 | jiangning | 2013-12-02 17:33:16 -0800 (Mon, 02 Dec 2013) | 2 lines

Add some missing AArch64 Neon intrinsics like vuqadd_s64 and friends.

------------------------------------------------------------------------

llvm-svn: 196673
2013-12-08 00:01:00 +00:00
Bill Wendling
5ab449eeb3 Merging r196190:
------------------------------------------------------------------------

llvm-svn: 196672
2013-12-08 00:00:06 +00:00
Bill Wendling
4ec99d3892 Merging r196189:
------------------------------------------------------------------------
r196189 | jiangning | 2013-12-02 17:28:55 -0800 (Mon, 02 Dec 2013) | 2 lines

Add some missing AArch64 Neon intrinsics like vmull_high_n_s16 and friends.

------------------------------------------------------------------------

llvm-svn: 196671
2013-12-07 23:59:52 +00:00
Bill Wendling
3d6588e179 Merging r196488:
------------------------------------------------------------------------
r196488 | rsmith | 2013-12-05 00:30:59 -0800 (Thu, 05 Dec 2013) | 4 lines

PR17983: Fix crasher bug in C++1y mode when performing a non-global array
delete on a class which has no array cookie and has no class-specific operator
new.

------------------------------------------------------------------------

llvm-svn: 196670
2013-12-07 23:53:50 +00:00
Bill Wendling
50ab40f542 Merging r196638:
------------------------------------------------------------------------
r196638 | arsenm | 2013-12-06 18:58:45 -0800 (Fri, 06 Dec 2013) | 1 line

Fix assert with copy from global through addrspacecast
------------------------------------------------------------------------

llvm-svn: 196668
2013-12-07 21:24:29 +00:00
Bill Wendling
b73458a893 Merging r196658:
------------------------------------------------------------------------
r196658 | d0k | 2013-12-07 08:12:52 -0800 (Sat, 07 Dec 2013) | 7 lines

CodeGen: Don't emit linkage on thunks that aren't emitted because they're vararg.

This can happen when we're trying to emit a thunk with available_externally
linkage with optimization enabled but bail because it doesn't make sense
for vararg functions.

PR18098.
------------------------------------------------------------------------

llvm-svn: 196666
2013-12-07 21:19:02 +00:00
Bill Wendling
046f899611 Merging r196658:
------------------------------------------------------------------------

llvm-svn: 196665
2013-12-07 21:18:41 +00:00
Bill Wendling
a43e3fda0c Merging r196391:
------------------------------------------------------------------------
r196391 | hliao | 2013-12-04 09:44:22 -0800 (Wed, 04 Dec 2013) | 5 lines

[X86] Check YMM31/ZMM31 as well

- No test case as there's no calling convention preserve YMM31/ZMM31 only


------------------------------------------------------------------------

llvm-svn: 196653
2013-12-07 09:39:53 +00:00
Bill Wendling
f63850063e Merging r196261:
------------------------------------------------------------------------
r196261 | hliao | 2013-12-03 01:17:32 -0800 (Tue, 03 Dec 2013) | 13 lines

Enhance the fix of PR17631

- The fix to PR17631 fixes part of the cases where 'vzeroupper' should
  not be issued before 'call' insn. There're other cases where helper
  calls will be inserted not limited to epilog. These helper calls do
  not follow the standard calling convention and won't clobber any YMM
  registers. (So far, all call conventions will clobber any or part of
  YMM registers.)
  This patch enhances the previous fix to cover more cases 'vzerosupper' should
  not be inserted by checking if that function call won't clobber any YMM
  registers and skipping it if so.


------------------------------------------------------------------------

llvm-svn: 196652
2013-12-07 09:39:35 +00:00
Bill Wendling
544cae41c5 Merging r196269:
------------------------------------------------------------------------
r196269 | jamesm | 2013-12-03 03:23:11 -0800 (Tue, 03 Dec 2013) | 5 lines

Addrspacecasts are no-ops on ARM.

Testcase added.


------------------------------------------------------------------------

llvm-svn: 196651
2013-12-07 09:36:35 +00:00
Bill Wendling
8156c448dd Merging r196369:
------------------------------------------------------------------------
r196369 | void | 2013-12-04 01:42:49 -0800 (Wed, 04 Dec 2013) | 1 line

Update email address.
------------------------------------------------------------------------

llvm-svn: 196650
2013-12-07 09:35:00 +00:00
Bill Wendling
badfc45f69 Merging r196294:
------------------------------------------------------------------------
r196294 | arnolds | 2013-12-03 08:33:06 -0800 (Tue, 03 Dec 2013) | 7 lines

opt: Mirror vectorization presets of clang

clang enables vectorization at optimization levels > 1 and size level < 2. opt
should behave similarily.

Loop vectorization and SLP vectorization can be disabled with the flags
-disable-(loop/slp)-vectorization.
------------------------------------------------------------------------

llvm-svn: 196649
2013-12-07 09:31:26 +00:00
Bill Wendling
028a1bb51a Merging r196611:
------------------------------------------------------------------------
r196611 | dexonsmith | 2013-12-06 13:48:36 -0800 (Fri, 06 Dec 2013) | 5 lines

Don't use isNullValue to evaluate ConstantExpr

ConstantExpr can evaluate to false even when isNullValue gives false.

Fixes PR18143.
------------------------------------------------------------------------

llvm-svn: 196614
2013-12-06 22:12:13 +00:00
Roman Divacky
00574fbb1f Mention sparc backend improvements.
llvm-svn: 196603
2013-12-06 20:04:30 +00:00
Bill Wendling
6c7f238298 Merging r196397:
------------------------------------------------------------------------
r196397 | gclayton | 2013-12-04 10:53:50 -0800 (Wed, 04 Dec 2013) | 7 lines

Added a new directory type for the "bool Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)" function: ePathTypeLLDBTempSystemDir

This will get the temporary directory on the current system.

Removed a call to tmpnam() and replaced it with a call to mktemp() using a template that will be in the temp directory.


------------------------------------------------------------------------

llvm-svn: 196598
2013-12-06 19:14:36 +00:00
Bill Wendling
a3a9825234 Merging r196538:
------------------------------------------------------------------------
r196538 | joerg | 2013-12-05 13:27:58 -0800 (Thu, 05 Dec 2013) | 2 lines

For NetBSD, use arm1176jzf-s as default CPU for ARMv6.

------------------------------------------------------------------------

llvm-svn: 196597
2013-12-06 19:12:59 +00:00
Bill Wendling
6d397a5f49 Merging r196532:
------------------------------------------------------------------------
r196532 | joerg | 2013-12-05 13:07:29 -0800 (Thu, 05 Dec 2013) | 2 lines

Pass down the target CPU to the system assembler for NetBSD/ARM.

------------------------------------------------------------------------

llvm-svn: 196596
2013-12-06 19:12:36 +00:00
Bill Wendling
49148e9903 Merging r196538:
------------------------------------------------------------------------

llvm-svn: 196595
2013-12-06 19:12:09 +00:00
Bill Wendling
0b6e7b244e Merging r196532:
------------------------------------------------------------------------

llvm-svn: 196594
2013-12-06 19:11:51 +00:00
Bill Wendling
d054efaddc Merging r196508:
------------------------------------------------------------------------
r196508 | arnolds | 2013-12-05 07:14:40 -0800 (Thu, 05 Dec 2013) | 12 lines

SLPVectorizer: An in-tree vectorized entry cannot also be a scalar external use

We were creating external uses for scalar values in MustGather entries that also
had a ScalarToTreeEntry (they also are present in a vectorized tuple). This
meant we would keep a value 'alive' as a scalar and vectorized causing havoc.
This is not necessary because when we create a MustGather vector we explicitly
create external uses entries for the insertelement instructions of the
MustGather vector elements.

Fixes PR18129.

radar://15582184
------------------------------------------------------------------------

llvm-svn: 196571
2013-12-06 09:10:19 +00:00
Bill Wendling
48b63362d9 Merging r196459:
------------------------------------------------------------------------
r196459 | rtrieu | 2013-12-04 18:52:09 -0800 (Wed, 04 Dec 2013) | 2 lines

Remove unused variable.

------------------------------------------------------------------------

llvm-svn: 196570
2013-12-06 09:07:48 +00:00
Bill Wendling
7bea388f9c Merging r196387:
------------------------------------------------------------------------
r196387 | aaronballman | 2013-12-04 07:32:26 -0800 (Wed, 04 Dec 2013) | 1 line

When parsing ignored attribute arguments, presuming the first argument is an unresolved identifier the same way that we do for unknown arguments. This resolves PR18075, where we regressed the handling of OpenBSD's bounded attribute.
------------------------------------------------------------------------

llvm-svn: 196522
2013-12-05 18:35:37 +00:00
Bill Wendling
ceb06de421 Revert r191049 and r191059. They were causing failures. See PR17975.
llvm-svn: 196521
2013-12-05 18:29:11 +00:00
Alexey Samsonov
93f7ae617f Merging r196501:
------------------------------------------------------------------------
r196501 | samsonov | 2013-12-05 16:53:36 +0400 (Thu, 05 Dec 2013) | 1 line

Run TSan/MSan lit tests only on 64-bit platforms
------------------------------------------------------------------------

llvm-svn: 196502
2013-12-05 12:57:55 +00:00
Kostya Serebryany
1f74d4dd9e [asan] port r196375 to 3.4
llvm-svn: 196478
2013-12-05 07:36:09 +00:00
Bill Wendling
e4bf668c15 Merging r196454:
------------------------------------------------------------------------
r196454 | faisalv | 2013-12-04 17:40:41 -0800 (Wed, 04 Dec 2013) | 43 lines

Fix init-captures for generic lambdas.

For an init capture, process the initialization expression
right away.  For lambda init-captures such as the following:
const int x = 10;
 auto L = [i = x+1](int a) {
   return [j = x+2,
          &k = x](char b) { };
 };
keep in mind that each lambda init-capture has to have:
 - its initialization expression executed in the context
   of the enclosing/parent decl-context.
 - but the variable itself has to be 'injected' into the
   decl-context of its lambda's call-operator (which has
   not yet been created).
Each init-expression is a full-expression that has to get
Sema-analyzed (for capturing etc.) before its lambda's
call-operator's decl-context, scope & scopeinfo are pushed on their
respective stacks.  Thus if any variable is odr-used in the init-capture
it will correctly get captured in the enclosing lambda, if one exists.
The init-variables above are created later once the lambdascope and
call-operators decl-context is pushed onto its respective stack.

Since the lambda init-capture's initializer expression occurs in the
context of the enclosing function or lambda, therefore we can not wait
till a lambda scope has been pushed on before deciding whether the
variable needs to be captured.  We also need to process all
lvalue-to-rvalue conversions and discarded-value conversions,
so that we can avoid capturing certain constant variables.
For e.g.,
 void test() {
  const int x = 10;
  auto L = [&z = x](char a) { <-- don't capture by the current lambda
    return [y = x](int i) { <-- don't capture by enclosing lambda
         return y;
    }
  };
If x was not const, the second use would require 'L' to capture, and
that would be an error.
Make sure TranformLambdaExpr is also aware of this.

Patch approved by Richard (Thanks!!) 
http://llvm-reviews.chandlerc.com/D2092
------------------------------------------------------------------------

llvm-svn: 196470
2013-12-05 05:25:04 +00:00
Bill Wendling
1be84437a2 Merging r196423:
------------------------------------------------------------------------
r196423 | faisalv | 2013-12-04 14:43:08 -0800 (Wed, 04 Dec 2013) | 17 lines

Fix for PR18052 - Lambdas within NSDMI's and default arguments in Nested classes.

Clang currently croaks on the following:
  struct X1 {
    struct X2 {
      int L = ([] (int i) { return i; })(2);
    };
  };

asserting that the containing lexical context of the lambda is not Sema's cur context, when pushing the lambda's decl context on.

This occurs because (prior to this patch) getContainingDC always returns the non-nested class for functions at class scope (even for inline member functions of nested classes (to account for delayed parsing of their bodies)).  The patch addresses this by having getContainingDC always return the lexical DC for a lambda's call operator.

Link to the bug: http://llvm.org/bugs/show_bug.cgi?id=18052
Link to Richard Smith's feedback on phabricator: http://llvm-reviews.chandlerc.com/D2331

Thanks!
------------------------------------------------------------------------

llvm-svn: 196469
2013-12-05 05:24:30 +00:00
Richard Sandiford
50e0cddf3e Merging r196370:
------------------------------------------------------------------------
r196370 | rsandifo | 2013-12-04 09:59:57 +0000 (Wed, 04 Dec 2013) | 14 lines

[SystemZ] Fix handling of pass-by-pointer arguments

I'd misunderstood getIndirect() to mean that the argument should be passed
as a pointer at the ABI level, with the ByVal argument choosing caller-copy
semantics over no-caller-copy (callee-copy-on-write) semantics.  But
getIndirect(x) actually means that x is passed by pointer at the IR
level but (at least on all other targets I looked at) directly at the
ABI level.  getIndirect(x, false) selects a pointer to a caller-made
copy, which is what SystemZ was aiming for.

This fixes a miscompilation of c-index-test.  Structure arguments were being
passed by pointer, but no copy was being made, so a write in the callee
stomped over a caller's local variable.

------------------------------------------------------------------------

llvm-svn: 196371
2013-12-04 10:02:36 +00:00
Kaelyn Uhrain
8ee6edbc6d Add blurb to release notes about typo correction improvements.
llvm-svn: 196343
2013-12-04 02:25:41 +00:00
Richard Sandiford
9829297e97 Merging r196267:
------------------------------------------------------------------------
r196267 | rsandifo | 2013-12-03 11:01:54 +0000 (Tue, 03 Dec 2013) | 12 lines

[SystemZ] Fix choice of known-zero mask in insertion optimization

The backend converts 64-bit ORs into subreg moves if the upper 32 bits
of one operand and the low 32 bits of the other are known to be zero.
It then tries to peel away redundant ANDs from the upper 32 bits.

Since AND masks are canonicalized to exclude known-zero bits,
the test ORs the mask and the known-zero bits together before
checking for redundancy.  The problem was that it was using the
wrong node when checking for known-zero bits, so could drop ANDs
that were still needed.

------------------------------------------------------------------------

llvm-svn: 196268
2013-12-03 11:05:09 +00:00
Bill Wendling
479ed0b9b4 Merging r196215:
------------------------------------------------------------------------
r196215 | alp | 2013-12-02 22:53:39 -0800 (Mon, 02 Dec 2013) | 1 line

Documentation typo corrections
------------------------------------------------------------------------

llvm-svn: 196234
2013-12-03 07:40:27 +00:00
Bill Wendling
2045e7beeb Merging r196206:
------------------------------------------------------------------------
r196206 | jiangning | 2013-12-02 21:36:55 -0800 (Mon, 02 Dec 2013) | 4 lines

Patch by Ana Pazos.

Fixed vcopy_laneq_f64 intrinsic implementation.

------------------------------------------------------------------------

llvm-svn: 196233
2013-12-03 07:39:25 +00:00
Bill Wendling
058803abe5 Merging r196153:
------------------------------------------------------------------------
r196153 | mcrosier | 2013-12-02 13:07:27 -0800 (Mon, 02 Dec 2013) | 2 lines

[AArch64] Implemented vcopy_lane patterns using scalar DUP instruction.
Patch by Ana Pazos!
------------------------------------------------------------------------

llvm-svn: 196232
2013-12-03 07:39:04 +00:00
Bill Wendling
661ce1401f Merging r196153:
------------------------------------------------------------------------

llvm-svn: 196231
2013-12-03 07:38:45 +00:00
Bill Wendling
c47f3c9e2d Merging r196151:
------------------------------------------------------------------------
r196151 | mcrosier | 2013-12-02 13:05:16 -0800 (Mon, 02 Dec 2013) | 2 lines

[AArch64] Implemented vcopy_lane patterns using scalar DUP instruction.
Patch by Ana Pazos!
------------------------------------------------------------------------

llvm-svn: 196230
2013-12-03 07:38:30 +00:00
Bill Wendling
4c3ca5ac5e Merging r196115:
------------------------------------------------------------------------
r196115 | joerg | 2013-12-02 08:12:05 -0800 (Mon, 02 Dec 2013) | 2 lines

Assume ARMv6 for NetBSD for now for strex/ldrex.

------------------------------------------------------------------------

llvm-svn: 196202
2013-12-03 05:11:19 +00:00
Richard Trieu
4b41534e85 Add info about Clang diagnostic improvements.
llvm-svn: 196193
2013-12-03 01:35:18 +00:00
Hans Wennborg
b1307b2c23 Mention clang-cl in the release notes
llvm-svn: 196166
2013-12-02 22:38:55 +00:00
Bill Wendling
8072be98b2 Merging r196104:
------------------------------------------------------------------------
r196104 | rafael | 2013-12-02 06:59:34 -0800 (Mon, 02 Dec 2013) | 1 line

Output .eh_frames on COFF too now that the integrated as is used on mingw.
------------------------------------------------------------------------

llvm-svn: 196137
2013-12-02 19:24:08 +00:00
Bill Wendling
875bec4c74 Merging r196069:
------------------------------------------------------------------------
r196069 | alp | 2013-12-01 23:15:33 -0800 (Sun, 01 Dec 2013) | 6 lines

Update the LTO GoldPlugin documentation

 * Update build instructions to reflect the current source tree layout.
 * Don't inflict CVS on readers; there's a perfectly good git mirror.
 * configure with --disable-werror making it possible to build using clang.
 * ar and nm-new now support the -plugin option.
------------------------------------------------------------------------

llvm-svn: 196136
2013-12-02 19:21:10 +00:00
Bill Wendling
1296dfe85c Merging r196100:
------------------------------------------------------------------------
r196100 | alp | 2013-12-02 06:17:47 -0800 (Mon, 02 Dec 2013) | 4 lines

Cut the gold plugin README down to size

This file hasn't been updated in years. Remove old information and point to
the current documentation at GoldPlugin.rst.
------------------------------------------------------------------------

llvm-svn: 196135
2013-12-02 19:20:45 +00:00
Bill Wendling
207f862fc5 Merging r196114:
------------------------------------------------------------------------
r196114 | joerg | 2013-12-02 08:09:34 -0800 (Mon, 02 Dec 2013) | 2 lines

NetBSD uses long derived size_t / ssize_t in all ARM ABIs.

------------------------------------------------------------------------

llvm-svn: 196134
2013-12-02 19:19:57 +00:00
Bill Wendling
aa7e683eaf Merging r195912:
------------------------------------------------------------------------
r195912 | whitequark | 2013-11-28 01:03:28 -0800 (Thu, 28 Nov 2013) | 1 line

[OCaml] Add a slash accidentally omitted from Makefile
------------------------------------------------------------------------

llvm-svn: 196133
2013-12-02 19:18:50 +00:00
Bill Wendling
d6c5347617 Merging r196129:
------------------------------------------------------------------------
r196129 | kkhoo | 2013-12-02 10:43:59 -0800 (Mon, 02 Dec 2013) | 1 line

Conservative fix for PR17827 - don't optimize a shift + and + compare sequence where the shift is logical unless the comparison is unsigned
------------------------------------------------------------------------

llvm-svn: 196132
2013-12-02 19:14:12 +00:00
Daniel Sanders
c4e06943b7 Merged r195756:
------------------------------------------------------------------------
r195756 | atanasyan | 2013-11-26 11:58:04 +0000 (Tue, 26 Nov 2013) | 1 line

[Mips] Pass -mmsa option to the assembler.
------------------------------------------------------------------------

llvm-svn: 196083
2013-12-02 10:14:43 +00:00
Daniel Sanders
de2f7f1dbc Merged r195249:
------------------------------------------------------------------------
r195249 | atanasyan | 2013-11-20 13:53:20 +0000 (Wed, 20 Nov 2013) | 2 lines

[Mips] Take in account the -mfp64 command line option when build paths
to the crt*.o files, libraries and headers for the MIPS FSFS toolchain.
------------------------------------------------------------------------

llvm-svn: 196082
2013-12-02 10:00:07 +00:00
Bill Wendling
c50835da58 Merging r196058:
------------------------------------------------------------------------
r196058 | marshall | 2013-12-01 19:24:33 -0800 (Sun, 01 Dec 2013) | 1 line

Fix for PRPR17934; based on a fix suggested by Peter Sommerlad
------------------------------------------------------------------------

llvm-svn: 196077
2013-12-02 07:41:26 +00:00
Bill Wendling
78a80cd666 Merging r196058:
------------------------------------------------------------------------

llvm-svn: 196076
2013-12-02 07:40:44 +00:00
Bill Wendling
0c970e2f54 Merging r196048:
------------------------------------------------------------------------
r196048 | d0k | 2013-12-01 07:09:32 -0800 (Sun, 01 Dec 2013) | 3 lines

CommentLexer: When proceeding with a typo corrected name don't clobber the token.

This would crash if the token is used in another diagnostic. PR18051.
------------------------------------------------------------------------

llvm-svn: 196075
2013-12-02 07:38:30 +00:00
Bill Wendling
c1f8b785dc Merging r196046:
------------------------------------------------------------------------
r196046 | tnorthover | 2013-12-01 06:16:24 -0800 (Sun, 01 Dec 2013) | 8 lines

ARM: fix bug in -Oz stack adjustment folding

Previously, we clobbered callee-saved registers when folding an "add
sp, #N" into a "pop {rD, ...}" instruction. This change checks whether
a register we're going to add to the "pop" could actually be live
outside the function before doing so and should fix the issue.

This should fix PR18081.
------------------------------------------------------------------------

llvm-svn: 196074
2013-12-02 07:38:06 +00:00
Bill Wendling
63fa617d1c Merging r195401:
------------------------------------------------------------------------
r195401 | lhames | 2013-11-21 16:46:32 -0800 (Thu, 21 Nov 2013) | 8 lines

Fix a typo where we were creating <def,kill> operands instead of
<def,dead> ones.

Add an assertion to make sure we catch this in the future.

Fixes <rdar://problem/15464559>.


------------------------------------------------------------------------

llvm-svn: 196073
2013-12-02 07:37:46 +00:00
Bill Wendling
e9dd613c95 Merging r196045:
------------------------------------------------------------------------
r196045 | d0k | 2013-12-01 03:48:10 -0800 (Sun, 01 Dec 2013) | 3 lines

Reenable ms inline asm test.

LLVM r196044 should make it pass.
------------------------------------------------------------------------

llvm-svn: 196072
2013-12-02 07:35:57 +00:00
Bill Wendling
daea5b6167 Merging r196045:
------------------------------------------------------------------------

llvm-svn: 196071
2013-12-02 07:35:19 +00:00
Bill Wendling
af00d97ff0 Merging r196044:
------------------------------------------------------------------------
r196044 | d0k | 2013-12-01 03:47:42 -0800 (Sun, 01 Dec 2013) | 6 lines

Revamp error checking in the ms inline asm parser.

- Actually abort when an error occurred.
- Check that the frontend lookup worked when parsing length/size/type operators.

Tested by a clang test. PR18096.
------------------------------------------------------------------------

llvm-svn: 196070
2013-12-02 07:35:04 +00:00
Bill Wendling
3e09fa6ff9 Merging r196050:
------------------------------------------------------------------------
r196050 | rafael | 2013-12-01 08:54:29 -0800 (Sun, 01 Dec 2013) | 5 lines

Handle CC and NoReturn when instantiating members of class templates.

Before we were considering them only when instantiating templates.

This fixes pr18033.
------------------------------------------------------------------------

llvm-svn: 196057
2013-12-02 02:05:28 +00:00
Daniel Sanders
c1645f9784 Merged r195973:
------------------------------------------------------------------------
r195973 | dsanders | 2013-11-30 13:47:57 +0000 (Sat, 30 Nov 2013) | 5 lines

[mips][msa] MSA loads and stores have a 10-bit offset. Account for this when lowering FrameIndex.

This prevents the compiler from emitting invalid ld.[bhwd]'s and st.[bhwd]'s
when the stack frame is between 512 and 32,768 bytes in size.

------------------------------------------------------------------------

Review of this commit by Matheus Almeida revealed that it is still possible to
emit invalid code (when the offset is not a multiple of the element size).
However, we agreed that this commit still represents an improvement since it
fixes many cases that previously emitted invalid code, and does not cause any
cases that previously emitted valid code to emit invalid code.

llvm-svn: 196049
2013-12-01 15:54:07 +00:00
Daniel Sanders
8fb25b83b5 Merged r195972:
------------------------------------------------------------------------
r195972 | dsanders | 2013-11-30 13:15:21 +0000 (Sat, 30 Nov 2013) | 5 lines

[mips][msa] A small refactor to reduce patch noise in my next commit

No functional change. An if-statement has been split into two nested if-statements.

------------------------------------------------------------------------

llvm-svn: 196047
2013-12-01 15:09:25 +00:00
Daniel Sanders
dc7476e2ce Merged from r195975 and r195976.
------------------------------------------------------------------------
r195975 | zjovanovic | 2013-11-30 19:12:28 +0000 (Sat, 30 Nov 2013) | 1 line

Fixed issue with microMIPS long branch.
------------------------------------------------------------------------
r195976 | zjovanovic | 2013-11-30 19:13:15 +0000 (Sat, 30 Nov 2013) | 1 line

Test case for issue with microMIPS long branch.
------------------------------------------------------------------------

To expand on those commit messages:
The immediate in a MIPS branch is multiplied by the instruction size before use
as an offset. For many MIPS ISA's this is 4 bytes, but for microMIPS it is 2
bytes. This commit corrects the scale factor used for microMIPS so that attempts
to use large offsets result in a valid sequence of instructions.

llvm-svn: 196043
2013-12-01 10:45:26 +00:00
Bill Wendling
12166d5aaf Merging r196038:
------------------------------------------------------------------------
r196038 | alp | 2013-11-30 21:08:12 -0800 (Sat, 30 Nov 2013) | 1 line

Fix a variety of user-visible and comment typos
------------------------------------------------------------------------

llvm-svn: 196039
2013-12-01 05:51:07 +00:00
Bill Wendling
9e7ad0b06a --- Reverse-merging r195823 into '.':
U    lib/MC/MCSectionCOFF.cpp
U    lib/CodeGen/TargetLoweringObjectFileImpl.cpp
U    test/MC/COFF/weak-symbol.ll
U    test/MC/COFF/tricky-names.ll
 G   .
--- Recording mergeinfo for reverse merge of r195823 into '.':
 G   .

llvm-svn: 196036
2013-12-01 04:40:32 +00:00
Bill Wendling
47027af861 Merging r195943:
------------------------------------------------------------------------

llvm-svn: 196035
2013-12-01 04:39:02 +00:00
Bill Wendling
d4a8aae27f Merging r195942:
------------------------------------------------------------------------

llvm-svn: 196034
2013-12-01 04:38:49 +00:00
Bill Wendling
e7248ebcae Merging r195941:
------------------------------------------------------------------------
r195941 | haoliu | 2013-11-28 18:11:22 -0800 (Thu, 28 Nov 2013) | 4 lines

AArch64: The pattern match should check the range of the immediate value.
Or we can generate some illegal instructions.
E.g. shrn2 v0.4s, v1.2d, #35. The legal range should be in [1, 16].

------------------------------------------------------------------------

llvm-svn: 196033
2013-12-01 04:38:36 +00:00
Bill Wendling
4d2ce489fd Merging r195940:
------------------------------------------------------------------------

llvm-svn: 196032
2013-12-01 04:38:19 +00:00
Bill Wendling
b6fb0d4cc6 Merging r195939:
------------------------------------------------------------------------
r195939 | jiangning | 2013-11-28 17:38:08 -0800 (Thu, 28 Nov 2013) | 2 lines

Add missing test case for bsl_f64 support of AArch64 NEON.

------------------------------------------------------------------------

llvm-svn: 196031
2013-12-01 04:38:07 +00:00
Bill Wendling
f8ba0c3dcf Merging r195938:
------------------------------------------------------------------------
r195938 | jiangning | 2013-11-28 17:37:15 -0800 (Thu, 28 Nov 2013) | 3 lines

Add missing pattern for supporting intrinsic function vbsl_f64 with
argument double floating point.

------------------------------------------------------------------------

llvm-svn: 196030
2013-12-01 04:37:52 +00:00
Bill Wendling
5cc146ea34 Merging r195937:
------------------------------------------------------------------------

llvm-svn: 196029
2013-12-01 04:37:38 +00:00
Bill Wendling
130fde3ba1 Merging r195936:
------------------------------------------------------------------------
r195936 | kevinqin | 2013-11-28 17:29:16 -0800 (Thu, 28 Nov 2013) | 1 line

[AArch64 NEON]Fix a assertion failure when disassemble SHLL instruction.
------------------------------------------------------------------------

llvm-svn: 196028
2013-12-01 04:37:25 +00:00
Bill Wendling
093c7994ef Merging r195932:
------------------------------------------------------------------------
r195932 | d0k | 2013-11-28 11:58:56 -0800 (Thu, 28 Nov 2013) | 3 lines

Silence sign-compare warning and reduce nesting.

No functionality change.
------------------------------------------------------------------------

llvm-svn: 196027
2013-12-01 04:37:07 +00:00
Bill Wendling
8394a14c7d Merging r195905:
------------------------------------------------------------------------
r195905 | jiangning | 2013-11-27 17:34:55 -0800 (Wed, 27 Nov 2013) | 3 lines

Remove the variable only used by assert to avoid the build failure
caused by build options [-Werror,-Wunused-variable].

------------------------------------------------------------------------

llvm-svn: 196026
2013-12-01 04:36:53 +00:00
Bill Wendling
421230e981 Merging r195903:
------------------------------------------------------------------------
r195903 | haoliu | 2013-11-27 17:07:45 -0800 (Wed, 27 Nov 2013) | 2 lines

AArch64: Fix a bug about disassembling post-index load single element to 4 vectors

------------------------------------------------------------------------

llvm-svn: 196025
2013-12-01 04:36:39 +00:00
Bill Wendling
626cd5ab1b Merging r195844:
------------------------------------------------------------------------

llvm-svn: 196024
2013-12-01 04:36:22 +00:00
Bill Wendling
8b7f2863ea Merging r195943:
------------------------------------------------------------------------
r195943 | haoliu | 2013-11-28 18:31:42 -0800 (Thu, 28 Nov 2013) | 2 lines

AArch64: Two intrinsics are expected to return float64 not float32 in arm_neon.h

------------------------------------------------------------------------

llvm-svn: 196023
2013-12-01 04:35:05 +00:00
Bill Wendling
bc3582b7f8 Merging r195942:
------------------------------------------------------------------------
r195942 | haoliu | 2013-11-28 18:13:17 -0800 (Thu, 28 Nov 2013) | 3 lines

Fix the problem that the range check for scalar narrow shift is too wide.
E.g. the immediate value of vshrns_n_s16 is [1,16], which should be [1,8].

------------------------------------------------------------------------

llvm-svn: 196022
2013-12-01 04:34:50 +00:00
Bill Wendling
86a3d38b88 Merging r195941:
------------------------------------------------------------------------

llvm-svn: 196021
2013-12-01 04:34:31 +00:00
Bill Wendling
0852043ec6 Merging r195940:
------------------------------------------------------------------------
r195940 | jiangning | 2013-11-28 17:38:49 -0800 (Thu, 28 Nov 2013) | 2 lines

Add missing intrinsic function vbsl_f64 for AArch64 NEON.

------------------------------------------------------------------------

llvm-svn: 196020
2013-12-01 04:34:18 +00:00
Bill Wendling
d139117d76 Merging r195939:
------------------------------------------------------------------------

llvm-svn: 196019
2013-12-01 04:34:03 +00:00
Bill Wendling
e065dd91a8 Merging r195938:
------------------------------------------------------------------------

llvm-svn: 196018
2013-12-01 04:33:50 +00:00
Bill Wendling
27cc9acb3d Merging r195937:
------------------------------------------------------------------------
r195937 | jiangning | 2013-11-28 17:29:57 -0800 (Thu, 28 Nov 2013) | 2 lines

Add missing intrinsic function vcombine_f64 for AArch64 NEON.

------------------------------------------------------------------------

llvm-svn: 196017
2013-12-01 04:33:38 +00:00
Bill Wendling
4a56fa1b48 Merging r195936:
------------------------------------------------------------------------

llvm-svn: 196016
2013-12-01 04:33:23 +00:00
Bill Wendling
2abc0b1a61 Merging r195932:
------------------------------------------------------------------------

llvm-svn: 196015
2013-12-01 04:33:11 +00:00
Bill Wendling
e482229e73 Merging r195905:
------------------------------------------------------------------------

llvm-svn: 196014
2013-12-01 04:32:59 +00:00
Bill Wendling
bb44de51fa Merging r195903:
------------------------------------------------------------------------

llvm-svn: 196013
2013-12-01 04:32:46 +00:00
Bill Wendling
80e295d499 Merging r195844:
------------------------------------------------------------------------
r195844 | jiangning | 2013-11-27 06:02:55 -0800 (Wed, 27 Nov 2013) | 2 lines

Fix the AArch64 NEON bug exposed by checking constant integer argument range of ACLE intrinsics.

------------------------------------------------------------------------

llvm-svn: 196012
2013-12-01 04:32:33 +00:00
Bill Wendling
7361a2de20 Merging r195843:
------------------------------------------------------------------------

llvm-svn: 196011
2013-12-01 04:32:18 +00:00
Bill Wendling
d0c46dbe0b Merging r195713:
------------------------------------------------------------------------

llvm-svn: 196010
2013-12-01 04:32:04 +00:00
Bill Wendling
735e39e5d0 Merging r195970:
------------------------------------------------------------------------
r195970 | joerg | 2013-11-29 16:38:16 -0800 (Fri, 29 Nov 2013) | 2 lines

NetBSD uses signed wchar_t on ARM platforms.

------------------------------------------------------------------------

llvm-svn: 196009
2013-12-01 04:22:48 +00:00
Bill Wendling
2e8337c7b0 Merging r195792:
------------------------------------------------------------------------
r195792 | rsmith | 2013-11-26 14:31:59 -0800 (Tue, 26 Nov 2013) | 2 lines

Remove unused entity from .td file.

------------------------------------------------------------------------

llvm-svn: 196008
2013-12-01 03:46:47 +00:00
Bill Wendling
f4f6168650 Merging r195777:
------------------------------------------------------------------------
r195777 | delesley | 2013-11-26 11:45:21 -0800 (Tue, 26 Nov 2013) | 1 line

Thread safety analysis: fix ICE due to missing null check on dyn_cast.
------------------------------------------------------------------------

llvm-svn: 196007
2013-12-01 03:45:49 +00:00
Bill Wendling
de1e7384be Merging r196004:
------------------------------------------------------------------------
r196004 | void | 2013-11-30 19:36:07 -0800 (Sat, 30 Nov 2013) | 3 lines

Use 'unsigned char' to get this past gcc error message:

  error: invalid conversion from 'unsigned char' to '{anonymous}::Sequence'
------------------------------------------------------------------------

llvm-svn: 196005
2013-12-01 03:36:55 +00:00
Bill Wendling
636122c819 Merging r195590:
------------------------------------------------------------------------
r195590 | chapuni | 2013-11-24 16:52:46 -0800 (Sun, 24 Nov 2013) | 1 line

SparcFrameLowering.cpp: Prune 'DL' [-Wunused-variable]
------------------------------------------------------------------------

llvm-svn: 196003
2013-12-01 03:30:51 +00:00
Bill Wendling
0c426e9b4a Merging r195915:
------------------------------------------------------------------------
r195915 | dsanders | 2013-11-28 01:36:44 -0800 (Thu, 28 Nov 2013) | 2 lines

As myself as code-owner of the MIPS backend (lib/Target/Mips/*)

------------------------------------------------------------------------

llvm-svn: 196002
2013-12-01 03:20:44 +00:00
Bill Wendling
2624711d0f Merging r195677:
------------------------------------------------------------------------
r195677 | dpeixott | 2013-11-25 11:11:13 -0800 (Mon, 25 Nov 2013) | 41 lines

ARM integrated assembler generates incorrect nop opcode

This patch fixes a bug in the assembler that was causing bad code to
be emitted.  When switching modes in an assembly file (e.g. arm to
thumb mode) we would always emit the opcode from the original mode.

Consider this small example:

$ cat align.s
.code 16
foo:
  add r0, r0
.align 3
  add r0, r0

$ llvm-mc -triple armv7-none-linux align.s -filetype=obj -o t.o
$ llvm-objdump -triple thumbv7 -d t.o
Disassembly of section .text:
foo:
       0:       00 44         add     r0, r0
       2:       00 f0 20 e3   blx #4195904
       6:       00 00         movs    r0, r0
       8:       00 44         add     r0, r0

This shows that we have actually emitted an arm nop (e320f000)
instead of a thumb nop. Unfortunately, this encodes to a thumb
branch which causes bad things to happen when compiling assembly
code with align directives.

The fix is to notify the ARMAsmBackend when we switch mode. The
MCMachOStreamer was already doing this correctly. This patch makes
the same change for the MCElfStreamer.

There is still a bug in the way nops are emitted for alignment
because the MCAlignment fragment does not store the correct mode.
The ARMAsmBackend will emit nops for the last mode it knew about. In
the example above, we still generate an arm nop if we add a `.code
32` to the end of the file.

PR18019

------------------------------------------------------------------------

llvm-svn: 196001
2013-12-01 03:19:10 +00:00
Bill Wendling
82658afc1f Merging r195881:
------------------------------------------------------------------------
r195881 | tstellar | 2013-11-27 13:23:39 -0800 (Wed, 27 Nov 2013) | 3 lines

R600: Expand vector FABS

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 196000
2013-12-01 03:15:22 +00:00
Bill Wendling
3211452b9d Merging r195879:
------------------------------------------------------------------------
r195879 | tstellar | 2013-11-27 13:23:29 -0800 (Wed, 27 Nov 2013) | 6 lines

R600/SI: Use SGPR_32 register class for 32-bit SMRD outputs

Writing to the M0 register from an SMRD instruction hangs the GPU, so
we need to use the SGPR_32 register class, which does not include M0.

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 195999
2013-12-01 03:14:50 +00:00
Bill Wendling
633fa63ef1 Merging r195878:
------------------------------------------------------------------------
r195878 | tstellar | 2013-11-27 13:23:20 -0800 (Wed, 27 Nov 2013) | 3 lines

R600: Add support for ISD::FROUND

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 195998
2013-12-01 03:13:21 +00:00
Bill Wendling
8899d16032 Merging r195843:
------------------------------------------------------------------------
r195843 | jiangning | 2013-11-27 06:02:25 -0800 (Wed, 27 Nov 2013) | 2 lines

Fix the AArch64 NEON bug exposed by checking constant integer argument range of ACLE intrinsics.

------------------------------------------------------------------------

llvm-svn: 195997
2013-12-01 03:11:03 +00:00
Bill Wendling
540ce1fd4c Merging r195812:
------------------------------------------------------------------------
r195812 | silvas | 2013-11-26 20:55:23 -0800 (Tue, 26 Nov 2013) | 3 lines

[docs] Mention gotcha regarding implicit BB numbering

Impetus for the clarification by Mikael Lyngvig.
------------------------------------------------------------------------

llvm-svn: 195996
2013-12-01 03:07:11 +00:00
Bill Wendling
98f23c1ba2 Merging r195804:
------------------------------------------------------------------------
r195804 | mcrosier | 2013-11-26 17:46:19 -0800 (Tue, 26 Nov 2013) | 1 line

[AArch64] Add support for NEON scalar floating-point absolute difference.
------------------------------------------------------------------------

llvm-svn: 195995
2013-12-01 03:06:29 +00:00
Bill Wendling
5bb4c5445c Merging r195803:
------------------------------------------------------------------------
r195803 | mcrosier | 2013-11-26 17:45:58 -0800 (Tue, 26 Nov 2013) | 1 line

[AArch64] Add support for NEON scalar floating-point absolute difference.
------------------------------------------------------------------------

llvm-svn: 195994
2013-12-01 03:06:07 +00:00
Bill Wendling
d673ee4de5 Merging r195788:
------------------------------------------------------------------------
r195788 | mcrosier | 2013-11-26 14:17:37 -0800 (Tue, 26 Nov 2013) | 2 lines

[AArch64] Add support for NEON scalar floating-point to integer convert
instructions.
------------------------------------------------------------------------

llvm-svn: 195993
2013-12-01 03:05:13 +00:00
Bill Wendling
09d71fe0b4 Merging r195789:
------------------------------------------------------------------------
r195789 | mcrosier | 2013-11-26 14:17:51 -0800 (Tue, 26 Nov 2013) | 2 lines

[AArch64] Add support for NEON scalar floating-point to integer convert
instructions.
------------------------------------------------------------------------

llvm-svn: 195992
2013-12-01 03:04:49 +00:00
Bill Wendling
7ef260d377 Merging r195787:
------------------------------------------------------------------------
r195787 | arnolds | 2013-11-26 14:11:23 -0800 (Tue, 26 Nov 2013) | 8 lines

LoopVectorizer: Truncate i64 trip counts of i32 phis if necessary

In signed arithmetic we could end up with an i64 trip count for an i32 phi.
Because it is signed arithmetic we know that this is only defined if the i32
does not wrap. It is therefore safe to truncate the i64 trip count to a i32
value.

Fixes PR18049.
------------------------------------------------------------------------

llvm-svn: 195991
2013-12-01 03:03:42 +00:00
Bill Wendling
5883e8815d Merging r195906:
------------------------------------------------------------------------
r195906 | majnemer | 2013-11-27 17:45:16 -0800 (Wed, 27 Nov 2013) | 5 lines

Sema: Assert that there are no pending local instantiations left

This should have been part of r195887, not sure how it slipped through
the cracks.

------------------------------------------------------------------------

llvm-svn: 195990
2013-12-01 02:10:35 +00:00
Bill Wendling
0c87436534 Merging r195897:
------------------------------------------------------------------------
r195897 | rikka | 2013-11-27 16:13:38 -0800 (Wed, 27 Nov 2013) | 1 line

Add a return statement to the func with an int return type.
------------------------------------------------------------------------

llvm-svn: 195989
2013-12-01 02:09:57 +00:00
Bill Wendling
93f76b4460 Merging r195887:
------------------------------------------------------------------------

llvm-svn: 195988
2013-12-01 02:09:07 +00:00
Bill Wendling
5c2317bd62 Merging r195877:
------------------------------------------------------------------------
r195877 | llunak | 2013-11-27 13:14:43 -0800 (Wed, 27 Nov 2013) | 3 lines

strip UTF-8 BOM in -frewrite-includes (PR#15664)


------------------------------------------------------------------------

llvm-svn: 195987
2013-12-01 02:07:35 +00:00
Bill Wendling
979bfd8a08 Merging r195827:
------------------------------------------------------------------------

llvm-svn: 195986
2013-12-01 02:05:46 +00:00
Sergey Matveev
d9e7b50f8d Merging r195983:
------------------------------------------------------------------------
r195983 | smatveev | 2013-12-01 01:54:43 +0400 (Sun, 01 Dec 2013) | 1 line

Update the LeakSanitizer documentation with a proper link.
------------------------------------------------------------------------

llvm-svn: 195984
2013-11-30 22:08:15 +00:00
Bill Wendling
19e8c127a4 Merging r195887:
------------------------------------------------------------------------
r195887 | majnemer | 2013-11-27 14:57:44 -0800 (Wed, 27 Nov 2013) | 9 lines

Sema: Instantiation of variable definitions weren't local enough

We wouldn't properly save and restore the pending local instantiations
we had built up prior to instantiation of a variable definition.  This
would lead to us instantiating too much causing crashes and other
general badness.

This fixes PR14374.

------------------------------------------------------------------------

llvm-svn: 195901
2013-11-28 00:34:28 +00:00
Bill Wendling
594fdb168b Merging r195827:
------------------------------------------------------------------------
r195827 | majnemer | 2013-11-27 00:20:38 -0800 (Wed, 27 Nov 2013) | 9 lines

Sema: Instantiate local class and their members appropriately

We would fail to instantiate them when the surrounding function was
instantiated. Instantiate the class and add it's members to the list of
pending instantiations, they should be resolved when we are finished
with the function's body.

This fixes PR9685.

------------------------------------------------------------------------

llvm-svn: 195900
2013-11-28 00:34:08 +00:00
Bill Wendling
1407663c78 Merging r195888:
------------------------------------------------------------------------
r195888 | rsmith | 2013-11-27 14:58:16 -0800 (Wed, 27 Nov 2013) | 2 lines

Add support for C++'s SD6 feature test macros.

------------------------------------------------------------------------

llvm-svn: 195899
2013-11-28 00:33:42 +00:00
Bill Wendling
e367e409fe Add blurb about PNaCl.
llvm-svn: 195885
2013-11-27 22:07:35 +00:00
Bill Wendling
4358ab7a82 Merging r195834:
------------------------------------------------------------------------
r195834 | whitequark | 2013-11-27 03:03:18 -0800 (Wed, 27 Nov 2013) | 11 lines

[OCaml] Embed rpath into stub libraries and native executables

This commit embeds a set of linker flags with hardcoded paths to
the LLVM shared library on --enable-shared builds into .cmxa files
and stub dynamic libraries. This solution closely follows existing
rules for rpath in the LLVM tools, which had to be modified because
of differences in toolchain.

Without this patch, OCaml tests as well as opam bindings broke,
as neither of those updates LD_LIBRARY_PATH to include
the $prefix/lib directory.
------------------------------------------------------------------------

llvm-svn: 195873
2013-11-27 19:51:24 +00:00
Bill Wendling
149d56cdb0 Merging r195782:
------------------------------------------------------------------------
r195782 | whitequark | 2013-11-26 12:40:34 -0800 (Tue, 26 Nov 2013) | 1 line

[OCaml] Embed the flags necessary for linking with libLLVM.so into .cmxa files
------------------------------------------------------------------------

llvm-svn: 195871
2013-11-27 19:42:48 +00:00
Bill Wendling
d7372d53f0 Merging r195576:
------------------------------------------------------------------------
r195576 | venkatra | 2013-11-24 12:23:25 -0800 (Sun, 24 Nov 2013) | 2 lines

[Sparc] Emit large negative adjustments to SP/FP with sethi+xor instead of sethi+or. This generates correct code for both sparc32 and sparc64.

------------------------------------------------------------------------

llvm-svn: 195870
2013-11-27 19:40:37 +00:00
Bill Wendling
85fee9fc53 Merging r195575:
------------------------------------------------------------------------
r195575 | venkatra | 2013-11-24 12:07:35 -0800 (Sun, 24 Nov 2013) | 2 lines

[Sparc]: Implement LEA pattern for sparcv9.

------------------------------------------------------------------------

llvm-svn: 195869
2013-11-27 19:40:19 +00:00
Bill Wendling
f29601d661 Merging r195574:
------------------------------------------------------------------------
r195574 | venkatra | 2013-11-24 10:41:49 -0800 (Sun, 24 Nov 2013) | 2 lines

[SparcV9]: Do not emit .register directives for global registers that are clobbered by calls but not used in the function itself.

------------------------------------------------------------------------

llvm-svn: 195868
2013-11-27 19:40:05 +00:00
Bill Wendling
3083593fb9 Merging r195573:
------------------------------------------------------------------------
r195573 | venkatra | 2013-11-24 09:41:41 -0800 (Sun, 24 Nov 2013) | 2 lines

[SparcV9] Enable custom lowering of DYNAMIC_STACKALLOC in sparc64.

------------------------------------------------------------------------

llvm-svn: 195867
2013-11-27 19:39:49 +00:00
Bill Wendling
16ca4c4a66 Merging r195798:
------------------------------------------------------------------------
r195798 | rafael | 2013-11-26 17:18:37 -0800 (Tue, 26 Nov 2013) | 9 lines

Use simple section names for COMDAT sections on COFF.

With this patch we use simple names for COMDAT sections (like .text or .bss).
This matches the MSVC behavior.

When merging it is the COMDAT symbol that is used to decide if two sections
should be merged, so there is no point in building a fancy name.

This survived a bootstrap on mingw32.
------------------------------------------------------------------------

llvm-svn: 195823
2013-11-27 06:44:45 +00:00
Bill Wendling
5bd6ab2592 Merging r195148:
------------------------------------------------------------------------
r195148 | rafael | 2013-11-19 11:52:52 -0800 (Tue, 19 Nov 2013) | 15 lines

Support multiple COFF sections with the same name but different COMDAT.

This is the first step to fix pr17918.

It extends the .section directive a bit, inspired by what the ELF one looks
like. The problem with using linkonce is that given

.section foo
.linkonce....

.section foo
.linkonce

we would already have switched sections when getting to .linkonce. The cleanest
solution seems to be to add the comdat information in the .section itself.
------------------------------------------------------------------------

llvm-svn: 195822
2013-11-27 06:44:18 +00:00
Bill Wendling
7638b420cf Merging r195779:
------------------------------------------------------------------------
r195779 | hliao | 2013-11-26 12:31:31 -0800 (Tue, 26 Nov 2013) | 7 lines

Fix PR18054

- Fix bug in (vsext (vzext x)) -> (vsext x) in SIGN_EXTEND_IN_REG
  lowering where we need to check whether x is a vector type (in-reg
  type) of i8, i16 or i32; otherwise, that optimization is not valid.


------------------------------------------------------------------------

llvm-svn: 195821
2013-11-27 06:36:20 +00:00
Bill Wendling
104cfa81a0 Merging r195791:
------------------------------------------------------------------------

llvm-svn: 195820
2013-11-27 06:30:19 +00:00
Bill Wendling
ac78862568 Merging r195791:
------------------------------------------------------------------------
r195791 | nadav | 2013-11-26 14:24:25 -0800 (Tue, 26 Nov 2013) | 4 lines

PR1860 - We can't save a list of ExtractElement instructions to CSE because some of these instructions
may be removed and optimized in future iterations. Instead we save a list of basic blocks that we need to CSE.


------------------------------------------------------------------------

llvm-svn: 195818
2013-11-27 05:35:16 +00:00
Bill Wendling
9a054a7fcf Merging r195773:
------------------------------------------------------------------------
r195773 | nadav | 2013-11-26 09:29:19 -0800 (Tue, 26 Nov 2013) | 6 lines

PR18060 - When we RAUW values with ExtractElement instructions in some cases
we generate PHI nodes with multiple entries from the same basic block but
with different values. Enabling CSE on ExtractElement instructions make sure
that all of the RAUWed instructions are the same.


------------------------------------------------------------------------

llvm-svn: 195817
2013-11-27 05:34:53 +00:00
Bill Wendling
04fe9916bd Merging r195768:
------------------------------------------------------------------------
r195768 | rafael | 2013-11-26 08:09:08 -0800 (Tue, 26 Nov 2013) | 3 lines

Don't call getMostRecentDecl when we know we have it.

On a Release build this takes the testcase in pr18055 from 0m3.892s to 0m1.452s.
------------------------------------------------------------------------

llvm-svn: 195816
2013-11-27 05:28:46 +00:00
Bill Wendling
e790ca30fc Merging r195303:
------------------------------------------------------------------------
r195303 | rsmith | 2013-11-20 17:53:02 -0800 (Wed, 20 Nov 2013) | 4 lines

PR10837: Warn if a null pointer constant is formed by a zero integer constant
expression that is not a zero literal, in C. This is a different, and more
targeted, approach than that in r194540.

------------------------------------------------------------------------

llvm-svn: 195815
2013-11-27 05:27:22 +00:00
Bill Wendling
70343174d6 Merging r195760:
------------------------------------------------------------------------
r195760 | ggreif | 2013-11-26 05:28:51 -0800 (Tue, 26 Nov 2013) | 1 line

fix a typo
------------------------------------------------------------------------

llvm-svn: 195811
2013-11-27 04:55:09 +00:00
Bill Wendling
c968ccf928 Merging r195769:
------------------------------------------------------------------------
r195769 | dyatkovskiy | 2013-11-26 08:11:03 -0800 (Tue, 26 Nov 2013) | 27 lines

PR17925 bugfix.

Short description.

This issue is about case of treating pointers as integers.
We treat pointers as different if they references different address space.
At the same time, we treat pointers equal to integers (with machine address
width). It was a point of false-positive. Consider next case on 32bit machine:

void foo0(i32 addrespace(1)* %p)
void foo1(i32 addrespace(2)* %p)
void foo2(i32 %p)

foo0 != foo1, while
foo1 == foo2 and foo0 == foo2.

As you can see it breaks transitivity. That means that result depends on order
of how functions are presented in module. Next order causes merging of foo0
and foo1: foo2, foo0, foo1
First foo0 will be merged with foo2, foo0 will be erased. Second foo1 will be
merged with foo2.
Depending on order, things could be merged we don't expect to.

The fix:
Forbid to treat any pointer as integer, except for those, who belong to address space 0.


------------------------------------------------------------------------

llvm-svn: 195810
2013-11-27 04:52:57 +00:00
Peter Zotov
2c5b0bd3ec Add a release note about OCaml bindings.
llvm-svn: 195786
2013-11-26 21:12:53 +00:00
Bill Wendling
a55660c196 Merging r195409:
------------------------------------------------------------------------
r195409 | jiangning | 2013-11-21 18:46:20 -0800 (Thu, 21 Nov 2013) | 2 lines

For AArch64, intrinsic vget_low_xxx can be optimized away.

------------------------------------------------------------------------

llvm-svn: 195765
2013-11-26 14:08:29 +00:00
Bill Wendling
ab3f1eeb92 Merging r195424:
------------------------------------------------------------------------
r195424 | haoliu | 2013-11-22 00:47:22 -0800 (Fri, 22 Nov 2013) | 4 lines

Fix the bugs about AArch64 Load/Store vector types and bitcast between i64 and vector types.
e.g. "%tmp = load <2 x i64>* %ptr" can't be selected. 
     "%tmp = bitcast i64 %in to <2 x i32>" can't be selected.

------------------------------------------------------------------------

llvm-svn: 195764
2013-11-26 13:35:26 +00:00
Bill Wendling
ea05f12bf0 Merging r195408:
------------------------------------------------------------------------
r195408 | jiangning | 2013-11-21 18:45:13 -0800 (Thu, 21 Nov 2013) | 2 lines

For AArch64 back-end instruction selection, lower Neon_Lowxxx with EXTRCT_SUBREG.

------------------------------------------------------------------------

llvm-svn: 195762
2013-11-26 13:34:03 +00:00
Bill Wendling
48ad4effd2 Merging r195713:
------------------------------------------------------------------------
r195713 | kevinqin | 2013-11-25 18:33:42 -0800 (Mon, 25 Nov 2013) | 1 line

[AArch64]Implement 128 bit register copy with NEON.
------------------------------------------------------------------------

llvm-svn: 195758
2013-11-26 12:29:45 +00:00
Bill Wendling
e1299bed25 Merging r195684:
------------------------------------------------------------------------
r195684 | rafael | 2013-11-25 12:50:03 -0800 (Mon, 25 Nov 2013) | 3 lines

Do the string comparison in the constructor instead of once per nop.

Thanks to Roman Divacky for the suggestion.
------------------------------------------------------------------------

llvm-svn: 195746
2013-11-26 11:20:48 +00:00
Bill Wendling
7468450bc3 Merging r195682:
------------------------------------------------------------------------
r195682 | rafael | 2013-11-25 12:46:18 -0800 (Mon, 25 Nov 2013) | 1 line

Use -triple to fix the test on non-ELF hosts.
------------------------------------------------------------------------

llvm-svn: 195745
2013-11-26 11:20:21 +00:00
Bill Wendling
167f1b8b75 Merging r195469:
------------------------------------------------------------------------
r195469 | dsanders | 2013-11-22 07:47:18 -0800 (Fri, 22 Nov 2013) | 4 lines

[mips][msa] Add test case that should have been added in r195456.



------------------------------------------------------------------------

llvm-svn: 195744
2013-11-26 11:17:57 +00:00
Bill Wendling
de326e3d25 Merging r195456:
------------------------------------------------------------------------
r195456 | dsanders | 2013-11-22 05:22:52 -0800 (Fri, 22 Nov 2013) | 4 lines

Fix typo in a comment added in r195455.

Credit to Matheus Almeida for spotting it.

------------------------------------------------------------------------

llvm-svn: 195743
2013-11-26 11:17:43 +00:00
Bill Wendling
a2b4acad88 Merging r195444:
------------------------------------------------------------------------
r195444 | dsanders | 2013-11-22 03:24:50 -0800 (Fri, 22 Nov 2013) | 4 lines

[mips][msa] Float vector constants cannot use ldi.[wd] directly. Bitcast from the appropriate integer vector type.

Fixes an instruction selection failure detected by llvm-stress.

------------------------------------------------------------------------

llvm-svn: 195742
2013-11-26 11:16:52 +00:00
Bill Wendling
10769845f7 Merging r195364:
------------------------------------------------------------------------
r195364 | dsanders | 2013-11-21 08:11:31 -0800 (Thu, 21 Nov 2013) | 12 lines

[mips][msa] Fix a corner case in performORCombine() when combining nodes into VSELECT.

Mask == ~InvMask asserts if the width of Mask and InvMask differ.
The combine isn't valid (with two exceptions, see below) if the widths differ
so test for this before testing Mask == ~InvMask.

In the specific cases of Mask=~0 and InvMask=0, as well as Mask=0 and
InvMask=~0, the combine is still valid. However, there are more appropriate
combines that could be used in these cases such as folding x & 0 to 0, or
x & ~0 to x.


------------------------------------------------------------------------

llvm-svn: 195741
2013-11-26 11:16:34 +00:00
Bill Wendling
6a184fc181 Merging r195343:
------------------------------------------------------------------------
r195343 | dsanders | 2013-11-21 03:40:14 -0800 (Thu, 21 Nov 2013) | 5 lines

[mips][msa/dsp] Only do DSP combines if DSP is enabled.

Fixes a crash (null pointer dereferenced) when MSA is enabled.


------------------------------------------------------------------------

llvm-svn: 195740
2013-11-26 11:16:17 +00:00
Bill Wendling
f6cfeadb87 Merging r195632:
------------------------------------------------------------------------
r195632 | tnorthover | 2013-11-25 01:52:59 -0800 (Mon, 25 Nov 2013) | 3 lines

X86: enable AVX2 under Haswell native compilation

Patch by Adam Strzelecki
------------------------------------------------------------------------

llvm-svn: 195737
2013-11-26 11:09:08 +00:00
Richard Sandiford
8640f0ccff Merging r195731:
------------------------------------------------------------------------
r195731 | rsandifo | 2013-11-26 10:53:16 +0000 (Tue, 26 Nov 2013) | 7 lines

[SystemZ] Fix incorrect use of RISBG for a zero-extended right shift

We would wrongly transform the testcase into the equivalent of an AND with 1.
The problem was that, when testing whether the shifted-in bits of the right
shift were significant, we used the width of the final zero-extended result
rather than the width of the shifted value.

------------------------------------------------------------------------

llvm-svn: 195736
2013-11-26 10:58:52 +00:00
Bill Wendling
a6650a9f96 Merging r195716:
------------------------------------------------------------------------
r195716 | kevinqin | 2013-11-25 19:26:47 -0800 (Mon, 25 Nov 2013) | 3 lines

Refactored the implementation of AArch64 NEON instruction ZIP, UZP
and TRN.
Fix a bug when mixed use of vget_high_u8() and vuzp_u8().
------------------------------------------------------------------------

llvm-svn: 195735
2013-11-26 10:57:43 +00:00
Bill Wendling
181cda7585 Merging r195716:
------------------------------------------------------------------------

llvm-svn: 195734
2013-11-26 10:56:42 +00:00
Bill Wendling
e901bb8069 Merging r195693:
------------------------------------------------------------------------
r195693 | joerg | 2013-11-25 14:44:20 -0800 (Mon, 25 Nov 2013) | 3 lines

Don't use T as template argument, it is part of the application
namespace.

------------------------------------------------------------------------

llvm-svn: 195733
2013-11-26 10:55:08 +00:00
Bill Wendling
0f4abf3f22 Merging r195693:
------------------------------------------------------------------------

llvm-svn: 195732
2013-11-26 10:54:48 +00:00
Bill Wendling
f161bec656 Merging r195679:
------------------------------------------------------------------------
r195679 | rafael | 2013-11-25 12:15:14 -0800 (Mon, 25 Nov 2013) | 12 lines

Don't use nopl in cpus that don't support it.

Patch by Mikulas Patocka. I added the test. I checked that for cpu names that
gas knows about, it also doesn't generate nopl.

The modified cpus:
i686 - there are i686-class CPUs that don't have nopl: Via c3, Transmeta
        Crusoe, Microsoft VirtualBox - see
        https://bbs.archlinux.org/viewtopic.php?pid=775414
k6, k6-2, k6-3, winchip-c6, winchip2 - these are 586-class CPUs
via c3 c3-2 - see https://bugs.archlinux.org/task/19733 as a proof that
        Via c3 and c3-Nehemiah don't have nopl
------------------------------------------------------------------------

llvm-svn: 195730
2013-11-26 10:46:15 +00:00
Bill Wendling
370fff6eb8 Merging r195669:
------------------------------------------------------------------------
r195669 | majnemer | 2013-11-25 09:50:19 -0800 (Mon, 25 Nov 2013) | 13 lines

[-cxx-abi microsoft] Create backrefs for <unnamed-type-`id'>

It wasn't possible for an anonymous type to show up inside of function arguments.
However, decltype (which MSVC added support for in 2010) makes this
possible.  Further, backrefs to these anonymous types can now be formed.

This fixes PR18022.

N.B. We do not, and very likely _will not_, support MSVC's bug where
subsequent typedefs of anonymous types leak into the linkage name; this
is a gross violation of the ABI.  A warning should be introduced to
inform our users of this particular shortcoming.

------------------------------------------------------------------------

llvm-svn: 195729
2013-11-26 10:45:43 +00:00
Bill Wendling
3a5500e7f6 Merging r195422:
------------------------------------------------------------------------
r195422 | alp | 2013-11-22 00:27:46 -0800 (Fri, 22 Nov 2013) | 5 lines

Tidy up the no-external-assembler diag

Diags aren't usually in the first person, and 'windows' isn't the correct
product spelling to use in prose. Sidestep issues completely by making this
error message platform-neutral.
------------------------------------------------------------------------

llvm-svn: 195726
2013-11-26 10:24:32 +00:00
Bill Wendling
f358b394d2 Merging r195420:
------------------------------------------------------------------------
r195420 | alp | 2013-11-22 00:00:20 -0800 (Fri, 22 Nov 2013) | 6 lines

Add txt file extension to VS solution's README

This matches other README.txt files in LLVM and makes things more obvious on
Windows where it's likely to be read. CRLFs are retained for the same reason.

Also fix Visual Studio product name.
------------------------------------------------------------------------

llvm-svn: 195725
2013-11-26 10:24:12 +00:00
Bill Wendling
0c57db8245 Merging r195587:
------------------------------------------------------------------------
r195587 | alp | 2013-11-24 16:40:53 -0800 (Sun, 24 Nov 2013) | 11 lines

Add heading and remove leftover personal email addresses

clang's attribute support is mature by now so replace Sean's warning and email
address with a standard LLVM copyright heading.

Also remove a personal email address and credit docstring from CGObjCGNU that
shouldn't have been there.

This is in line with the LLVM developer policy introduced in r45410.
Contributors can add themselves to CREDITS.txt while active module owners are
listed in CODE_OWNERS.TXT.
------------------------------------------------------------------------

llvm-svn: 195724
2013-11-26 10:23:53 +00:00
Bill Wendling
30ae23573a Merging r195710:
------------------------------------------------------------------------
r195710 | alp | 2013-11-25 17:30:10 -0800 (Mon, 25 Nov 2013) | 10 lines

Unbreak -fms-extensions with GNU libc headers

GNU libc uses '__uptr' as a member name in C mode, conflicting with the
eponymous MSVC pointer modifier keyword.

Detect and mark the token as an identifier when these specific conditions are
met. __uptr will continue to work as a keyword for the remainder of the
translation unit.

Fixes PR17824.
------------------------------------------------------------------------

llvm-svn: 195721
2013-11-26 04:10:07 +00:00
Bill Wendling
95aa6eaab7 Merging r195687:
------------------------------------------------------------------------
r195687 | rsmith | 2013-11-25 13:30:29 -0800 (Mon, 25 Nov 2013) | 3 lines

PR18044: Reject declarations of enumtype::X early to avoid an assertion in
downstream code.

------------------------------------------------------------------------

llvm-svn: 195720
2013-11-26 04:09:45 +00:00
Bill Wendling
3c2c4e6baa Merging r195620:
------------------------------------------------------------------------
r195620 | rsmith | 2013-11-24 23:07:05 -0800 (Sun, 24 Nov 2013) | 3 lines

Take cv-qualifiers on fields of class type into account when determining
whether a defaulted special member function should be deleted.

------------------------------------------------------------------------

llvm-svn: 195719
2013-11-26 04:05:40 +00:00
Bill Wendling
761173e3f7 Merging r195379:
------------------------------------------------------------------------
r195379 | hans | 2013-11-21 14:47:21 -0800 (Thu, 21 Nov 2013) | 7 lines

CMake: Some changes to package version names:

- Allow overriding PACKAGE_VERSION from the command-line
- Use PACKAGE_VERSION to set CPACK_PACKAGE_VERSION (used by the Win installer)
- Don't include the version number in the CPack install dir or registry key.

Differential revision: http://llvm-reviews.chandlerc.com/D2245
------------------------------------------------------------------------

llvm-svn: 195674
2013-11-25 18:34:26 +00:00
Bill Wendling
17eaf818cb Merging r195670:
------------------------------------------------------------------------
r195670 | void | 2013-11-25 10:05:22 -0800 (Mon, 25 Nov 2013) | 5 lines

Unrevert r195599 with testcase fix.

I'm not sure how it was checking for the wrong values...
PR18023.

------------------------------------------------------------------------

llvm-svn: 195672
2013-11-25 18:08:07 +00:00
Bill Wendling
aa7e1074a0 Merging r195636:
------------------------------------------------------------------------
r195636 | aemerson | 2013-11-25 03:24:18 -0800 (Mon, 25 Nov 2013) | 2 lines

Revert r195599 as it broke the builds.

------------------------------------------------------------------------

llvm-svn: 195671
2013-11-25 18:07:39 +00:00
Sergey Matveev
6d6d30bb99 Merging r195652:
------------------------------------------------------------------------
r195652 | smatveev | 2013-11-25 19:54:31 +0400 (Mon, 25 Nov 2013) | 3 lines

[lsan] Unbreak lsan_testlib.cc.

Also, add missing logging output.
------------------------------------------------------------------------

llvm-svn: 195668
2013-11-25 17:40:17 +00:00
Sergey Matveev
66ac044bc2 Merging r195643:
------------------------------------------------------------------------
r195643 | smatveev | 2013-11-25 18:30:37 +0400 (Mon, 25 Nov 2013) | 1 line

[lsan] Add a missing file.
------------------------------------------------------------------------

llvm-svn: 195667
2013-11-25 17:39:55 +00:00
Sergey Matveev
78c7eff20d Merging r195642:
------------------------------------------------------------------------
r195642 | smatveev | 2013-11-25 18:25:36 +0400 (Mon, 25 Nov 2013) | 5 lines

[lsan] Unbreak standalone LSan's initialization by making it more like ASan's.

No longer allow interceptors to be called during initialization, use the preinit
array (instead of initializing at the first call to an intercepted function) and
adopt the calloc() hack from ASan.
------------------------------------------------------------------------

llvm-svn: 195666
2013-11-25 17:39:36 +00:00
Sergey Matveev
31cb20415d Merging r195570:
------------------------------------------------------------------------
r195570 | smatveev | 2013-11-24 18:28:18 +0400 (Sun, 24 Nov 2013) | 4 lines

[lsan] Use real memset to clear memory in standalone LSan.

Performance improvement. Also, the allocator was using CompactSizeClassMap for
no good reason, so I switched it to DefaultSizeClassMap.
------------------------------------------------------------------------

llvm-svn: 195665
2013-11-25 17:39:12 +00:00
Daniel Sanders
8d0418ed0c Merging r195635:
------------------------------------------------------------------------
r195635 | dsanders | 2013-11-25 11:14:43 +0000 (Mon, 25 Nov 2013) | 19 lines

Fixed tryFoldToZero() for vector types that need expansion.

Summary:
Moved the requirement for SelectionDAG::getConstant() to return legally
typed nodes slightly earlier. There were two optional DAGCombine passes
that were missed out and were required to produce type-legal DAGs.

Simplified a code-path in tryFoldToZero() to use SelectionDAG::getConstant().
This provides support for both promoted and expanded vector types whereas the
previous code only supported promoted vector types.

Fixes a "Type for zero vector elements is not legal" assertion detected by
an llvm-stress generated test.

Reviewers: resistor

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D2251
------------------------------------------------------------------------

llvm-svn: 195651
2013-11-25 15:53:39 +00:00
Pekka Jaaskelainen
bcd6920382 Added our Clang/LLVM using projects (pocl and TCE) to the
external projects using LLVM. Ordered the list alphabetically.

llvm-svn: 195639
2013-11-25 12:06:04 +00:00
Bill Wendling
e468c2b3e1 Merging r195556:
------------------------------------------------------------------------
r195556 | akirtzidis | 2013-11-23 10:41:35 -0800 (Sat, 23 Nov 2013) | 3 lines

[CodeGen] If there is a function definition with duplicate mangled name, emit an error instead of asserting.

rdar://15522601 & http://llvm.org/PR18031
------------------------------------------------------------------------

llvm-svn: 195623
2013-11-25 07:42:52 +00:00
Bill Wendling
c245a8a0c8 Merging r195136:
------------------------------------------------------------------------
r195136 | marshall | 2013-11-19 10:05:03 -0800 (Tue, 19 Nov 2013) | 1 line

Patch by Bruce Mitchener. Change all references to EMSCRIPTEN to __EMSCRIPTEN__. If you're not using the PP symbol EMSCRIPTEN, then you should see no functionality change.
------------------------------------------------------------------------

llvm-svn: 195622
2013-11-25 07:41:30 +00:00
Bill Wendling
7c0578e357 Merging r195136:
------------------------------------------------------------------------

llvm-svn: 195621
2013-11-25 07:41:12 +00:00
Bill Wendling
27c8f7a38d Merging r195591:
------------------------------------------------------------------------
r195591 | haoliu | 2013-11-24 17:53:26 -0800 (Sun, 24 Nov 2013) | 5 lines

Fixed a bug about disassembling AArch64 post-index load/store single element instructions.
ie. echo "0x00 0x04 0x80 0x0d" | ../bin/llvm-mc -triple=aarch64 -mattr=+neon -disassemble
    echo "0x00 0x00 0x80 0x0d" | ../bin/llvm-mc -triple=aarch64 -mattr=+neon -disassemble
will be disassembled into the same instruction st1 {v0b}[0], [x0], x0.

------------------------------------------------------------------------

llvm-svn: 195619
2013-11-25 06:23:37 +00:00
Bill Wendling
084efceaea Merging r195558:
------------------------------------------------------------------------
r195558 | alp | 2013-11-23 14:11:57 -0800 (Sat, 23 Nov 2013) | 8 lines

Fix a SSE2 intrinsics typo

Full discourse at:

  http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20131104/092514.html
  http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-November/068124.html

Patch by Dimitry Andric and Alexey Dokuchaev!
------------------------------------------------------------------------

llvm-svn: 195617
2013-11-25 05:44:52 +00:00
Bill Wendling
eef0002611 Merging r195547:
------------------------------------------------------------------------

llvm-svn: 195616
2013-11-25 05:43:13 +00:00
Bill Wendling
feb38ed333 Merging r195501:
------------------------------------------------------------------------
r195501 | joerg | 2013-11-22 13:34:35 -0800 (Fri, 22 Nov 2013) | 5 lines

Adjust r194296 to not apply the alias replacement for externally
available always-inline functions. This breaks libc++'s locale
implementation. Code generation for this case should be fixed, but this
is a stop gap fix for clang 3.4.

------------------------------------------------------------------------

llvm-svn: 195615
2013-11-25 05:40:33 +00:00
Bill Wendling
ce8265a57d Merging r195329:
------------------------------------------------------------------------
r195329 | apazos | 2013-11-21 00:15:01 -0800 (Thu, 21 Nov 2013) | 5 lines

Implemented Neon scalar vdup_lane intrinsics.

Fixed scalar dup alias and added test case.


------------------------------------------------------------------------

llvm-svn: 195614
2013-11-25 05:39:42 +00:00
Bill Wendling
fff4687f12 Merging r195326:
------------------------------------------------------------------------
r195326 | apazos | 2013-11-20 23:36:33 -0800 (Wed, 20 Nov 2013) | 6 lines

Implemented Neon scalar by element intrinsics.

Intrinsics implemented: vqdmull_lane, vqdmulh_lane, vqrdmulh_lane,
vqdmlal_lane, vqdmlsl_lane scalar Neon intrinsics.


------------------------------------------------------------------------

llvm-svn: 195613
2013-11-25 05:39:19 +00:00
Bill Wendling
c647dedda2 Merging r195330:
------------------------------------------------------------------------
r195330 | apazos | 2013-11-21 00:16:15 -0800 (Thu, 21 Nov 2013) | 5 lines

Implemented Neon scalar vdup_lane intrinsics.

Fixed scalar dup alias and added test case.


------------------------------------------------------------------------

llvm-svn: 195612
2013-11-25 05:38:48 +00:00
Bill Wendling
8d6eaee767 Merging r195327:
------------------------------------------------------------------------
r195327 | apazos | 2013-11-20 23:37:04 -0800 (Wed, 20 Nov 2013) | 6 lines

Implemented Neon scalar by element intrinsics.

Intrinsics implemented: vqdmull_lane, vqdmulh_lane, vqrdmulh_lane,
vqdmlal_lane, vqdmlsl_lane scalar Neon intrinsics.


------------------------------------------------------------------------

llvm-svn: 195611
2013-11-25 05:38:27 +00:00
Bill Wendling
d98a5018ff Merging r195514:
------------------------------------------------------------------------
r195514 | tstellar | 2013-11-22 15:07:58 -0800 (Fri, 22 Nov 2013) | 6 lines

R600/SI: Fixing handling of condition codes

We were ignoring the ordered/onordered bits and also the signed/unsigned
bits of condition codes when lowering the DAG to MachineInstrs.

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 195609
2013-11-25 05:36:37 +00:00
Bill Wendling
c3d6718503 Merging r195528:
------------------------------------------------------------------------
r195528 | chandlerc | 2013-11-22 16:48:34 -0800 (Fri, 22 Nov 2013) | 7 lines

Migrate metadata information from scalar to vector instructions during
SLP vectorization. Based on the code in BBVectorizer.

Fixes PR17741.

Patch by Raul Silvera, reviewed by Hal and Nadav. Reformatted by my
driving of clang-format. =]
------------------------------------------------------------------------

llvm-svn: 195608
2013-11-25 05:27:31 +00:00
Bill Wendling
6da3591996 Merging r195479:
------------------------------------------------------------------------
r195479 | hans | 2013-11-22 10:25:43 -0800 (Fri, 22 Nov 2013) | 4 lines

VS integration: use the correct registry key after r195379

I changed the registry key in that commit, but forgot to update
the integration files. This change makes them use the same variable.
------------------------------------------------------------------------

llvm-svn: 195607
2013-11-25 05:23:29 +00:00
Bill Wendling
9ffaa79622 Merging r195493:
------------------------------------------------------------------------
r195493 | arsenm | 2013-11-22 11:24:39 -0800 (Fri, 22 Nov 2013) | 6 lines

StructurizeCFG: Fix verification failure with some loops.

If the beginning of the loop was also the entry block
of the function, branches were inserted to the entry block
which isn't allowed. If this occurs, create a new dummy
function entry block that branches to the start of the loop.
------------------------------------------------------------------------

llvm-svn: 195606
2013-11-25 05:23:10 +00:00
Bill Wendling
b2d55e6818 Merging r195492:
------------------------------------------------------------------------
r195492 | arsenm | 2013-11-22 11:24:37 -0800 (Fri, 22 Nov 2013) | 1 line

StructurizeCFG: Fix inverting a branch on an argument
------------------------------------------------------------------------

llvm-svn: 195605
2013-11-25 05:22:53 +00:00
Bill Wendling
96ca0ef2b2 Merging r195491:
------------------------------------------------------------------------
r195491 | probinson | 2013-11-22 11:11:24 -0800 (Fri, 22 Nov 2013) | 11 lines

Teach ISel not to optimize 'optnone' functions (revised).

Improvements over r195317:
- Set/restore EnableFastISel flag instead of just running FastISel within
  SelectAllBasicBlocks; the flag is checked in various places, and
  FastISel won't run properly if those places don't do the right thing.
- Test looks for normal ISel versus FastISel behavior, and not
  something more subtle that doesn't work everywhere.

Based on work by Andrea Di Biagio.

------------------------------------------------------------------------

llvm-svn: 195604
2013-11-25 05:21:50 +00:00
Bill Wendling
bc9582ac6f Merging r195477:
------------------------------------------------------------------------
r195477 | rafael | 2013-11-22 09:58:12 -0800 (Fri, 22 Nov 2013) | 13 lines

Add a fixed version of r195470 back.

The fix is simply to use CurI instead of I when handling aliases to
avoid accessing a invalid iterator.

original message:

Convert linkonce* to weak* instead of strong.

Also refactor the logic into a helper function. This is an important improve
on mingw where the linker complains about mixed weak and strong symbols.
Converting to weak ensures that the symbol is not dropped, but keeps in a
comdat, making the linker happy.
------------------------------------------------------------------------

llvm-svn: 195603
2013-11-25 05:20:58 +00:00
Bill Wendling
26aaff7e02 Merging r195476:
------------------------------------------------------------------------
r195476 | hliao | 2013-11-22 09:56:57 -0800 (Fri, 22 Nov 2013) | 6 lines

Fix PR18014

- When simplifying the mask generation for BLEND, check whether that mask is
  also consumed by other non-BLEND insns. If true, skip that simplification.


------------------------------------------------------------------------

llvm-svn: 195602
2013-11-25 05:20:10 +00:00
Bill Wendling
5b8b13a3b4 Merging r195432:
------------------------------------------------------------------------
r195432 | haoliu | 2013-11-22 01:24:41 -0800 (Fri, 22 Nov 2013) | 3 lines

Fix a Cygwin build failure caused by enum values starting with '_', which is conflicted with some platform macros.    
This patch only renames variables, no functional change.

------------------------------------------------------------------------

llvm-svn: 195601
2013-11-25 05:08:17 +00:00
Bill Wendling
29c77c166d Merging r195599:
------------------------------------------------------------------------
r195599 | void | 2013-11-24 21:01:21 -0800 (Sun, 24 Nov 2013) | 4 lines

Don't look past volatile loads.

A volatile load should block us from trying to coalesce stores.
PR18023
------------------------------------------------------------------------

llvm-svn: 195600
2013-11-25 05:02:20 +00:00
Bill Wendling
307b249d3c Merging r195567:
------------------------------------------------------------------------
r195567 | void | 2013-11-23 21:29:35 -0800 (Sat, 23 Nov 2013) | 1 line

Default to a better compression algorithm.
------------------------------------------------------------------------

llvm-svn: 195568
2013-11-24 05:30:06 +00:00
Bill Wendling
0abddae898 Merging r195547:
------------------------------------------------------------------------
r195547 | d0k | 2013-11-23 02:57:32 -0800 (Sat, 23 Nov 2013) | 9 lines

Enable non-fragile ABI for the ObjFW runtime

The following patch enables the non-fragile ABI for the ObjFW runtime.

However, I noticed that it is not possible anymore to disable it with
-fno-objc-nonfragile-abi like it was before. I think this functionality should
be restored, but I guess this is not in scope for 3.4 anymore.

Patch by Jonathan Schleifer!
------------------------------------------------------------------------

llvm-svn: 195548
2013-11-23 11:05:49 +00:00
Bill Wendling
99f9506689 Merging r195439:
------------------------------------------------------------------------
r195439 | kcc | 2013-11-22 02:30:39 -0800 (Fri, 22 Nov 2013) | 3 lines

Revert r195318 as it causes miscompilation (PR18029)


------------------------------------------------------------------------

llvm-svn: 195478
2013-11-22 18:01:22 +00:00
Richard Sandiford
be1fa4adae Add file missing from r195474.
llvm-svn: 195475
2013-11-22 17:37:52 +00:00
Richard Sandiford
aa3c656de1 Merging r195473:
------------------------------------------------------------------------
r195473 | rsandifo | 2013-11-22 17:28:28 +0000 (Fri, 22 Nov 2013) | 10 lines

[SystemZ] Fix TMHH and TMHL usage for z10 with -O0

I've no idea why I decided to handle TMxx differently from all the other
high/low logic operations, but it was a stupid thing to do.  The high
registers aren't available as separate 32-bit registers on z10,
so subreg_h32 can't be used on a GR64 there.

I've normally been testing with z196 and with -O3 and so hadn't noticed
this until now.

------------------------------------------------------------------------

llvm-svn: 195474
2013-11-22 17:37:28 +00:00
Alexander Potapenko
bd769691fe [ASan] Backport r195125, r195132, r195216 to LLVM 3.4 branch.
These patches should fix building asan_iossim_dynamic (the ASan runtime targeting iOS simulator).

llvm-svn: 195465
2013-11-22 14:31:50 +00:00
Evgeniy Stepanov
6721a46cb4 Merging r195442:
------------------------------------------------------------------------
r195442 | eugenis | 2013-11-22 15:01:43 +0400 (Fri, 22 Nov 2013) | 2 lines

[sanitizer] Fix kernel headers compatibility on powerpc64.

------------------------------------------------------------------------

llvm-svn: 195464
2013-11-22 14:01:23 +00:00
Evgeniy Stepanov
c87cf0ab5c Merging r195436:
------------------------------------------------------------------------
r195436 | eugenis | 2013-11-22 14:09:34 +0400 (Fri, 22 Nov 2013) | 2 lines

[sanitizer] Add kernel_stat definitions for arm.

------------------------------------------------------------------------

llvm-svn: 195463
2013-11-22 14:01:03 +00:00
Evgeniy Stepanov
92985647af Merging r195434:
------------------------------------------------------------------------
r195434 | eugenis | 2013-11-22 13:32:39 +0400 (Fri, 22 Nov 2013) | 4 lines

[sanitizer] Restore perf_event_attr handling.

This time in a forward/backward compatible way.

------------------------------------------------------------------------

llvm-svn: 195462
2013-11-22 14:00:45 +00:00
Evgeniy Stepanov
4a18cddc2b Merging r195433:
------------------------------------------------------------------------
r195433 | eugenis | 2013-11-22 13:26:10 +0400 (Fri, 22 Nov 2013) | 2 lines

[sanitizer] Fix build.

------------------------------------------------------------------------

llvm-svn: 195461
2013-11-22 14:00:23 +00:00
Evgeniy Stepanov
2381f13d4a Merging r195427:
------------------------------------------------------------------------
r195427 | eugenis | 2013-11-22 13:01:50 +0400 (Fri, 22 Nov 2013) | 10 lines

[sanitizer] Change the way we use certain linux kernel headers.

Some linux headers are broken on older kernels.
Instead of depending on the constants and types from such headers directly,
we provide our own definitions and then verify them with compile-time
assertions. This makes the dependency on the headers test-only and would allow
switching to some other way of testing on older kernels, or even disable the
tests as the last resort (after all, kernel interfaces are supposed to be
stable).

------------------------------------------------------------------------

llvm-svn: 195460
2013-11-22 14:00:02 +00:00
Bill Wendling
fffa1fd0a3 Merging r195423:
------------------------------------------------------------------------
r195423 | haoliu | 2013-11-22 00:34:54 -0800 (Fri, 22 Nov 2013) | 2 lines

Revert last change by haoliu because of buildbot failure.

------------------------------------------------------------------------

llvm-svn: 195429
2013-11-22 09:12:13 +00:00
Bill Wendling
f5edf6f43b Merging r195421:
------------------------------------------------------------------------
r195421 | haoliu | 2013-11-22 00:17:16 -0800 (Fri, 22 Nov 2013) | 5 lines

Fix a Cygwin build failure caused by enum values starting with '_', which is conflicted with some platform macros.
This solution only renames variables, no functional change.

NOTE: This is a candidate for the 3.4 branch.

------------------------------------------------------------------------

llvm-svn: 195428
2013-11-22 09:11:47 +00:00
Bill Wendling
feb500a0f7 Merging r195399:
------------------------------------------------------------------------
r195399 | tstellar | 2013-11-21 16:41:08 -0800 (Thu, 21 Nov 2013) | 10 lines

R600: Implement TargetInstrInfo::isLegalToSplitMBBAt()

Splitting a basic block will create a new ALU clause, so we need to make
sure we aren't moving uses of registers that are local to their
current clause into a new one.

I had a test case for this, but unfortunately unrelated schedule changes
invalidated it, and I wasn't been able to come up with another one.

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 195415
2013-11-22 05:18:37 +00:00
Bill Wendling
9047fb418e Merging r195398:
------------------------------------------------------------------------
r195398 | tstellar | 2013-11-21 16:41:05 -0800 (Thu, 21 Nov 2013) | 7 lines

SelectionDAG: Optimize expansion of vec_type = BITCAST scalar_type

The legalizer can now do this type of expansion for more
type combinations without loading and storing to and
from the stack.

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 195414
2013-11-22 05:18:23 +00:00
Bill Wendling
3a44e8e5f8 Merging r195397:
------------------------------------------------------------------------
r195397 | tstellar | 2013-11-21 16:39:23 -0800 (Thu, 21 Nov 2013) | 11 lines

Split SETCC if VSELECT requires splitting too.

This patch is a rewrite of the original patch commited in r194542. Instead of
relying on the type legalizer to do the splitting for us, we now peform the
splitting ourselves in the DAG combiner. This is necessary for the case where
the vector mask is a legal type after promotion and still wouldn't require
splitting.

Patch by: Juergen Ributzka

NOTE: This is a candidate for the 3.4 branch.
------------------------------------------------------------------------

llvm-svn: 195413
2013-11-22 05:18:07 +00:00
Bill Wendling
cfd74ba3ff Merging r195156:
------------------------------------------------------------------------
r195156 | ributzka | 2013-11-19 13:20:17 -0800 (Tue, 19 Nov 2013) | 3 lines

[DAG] Refactor vector splitting code in SelectionDAG. No functional change intended.

Reviewed by Tom
------------------------------------------------------------------------

llvm-svn: 195412
2013-11-22 05:17:44 +00:00
Bill Wendling
4e9d061986 Merging r195384:
------------------------------------------------------------------------
r195384 | rsmith | 2013-11-21 15:30:57 -0800 (Thu, 21 Nov 2013) | 2 lines

PR18013: Don't assert diagnosing a bad std::initializer_list construction.

------------------------------------------------------------------------

llvm-svn: 195394
2013-11-22 00:01:44 +00:00
Bill Wendling
126b1afe1b Merging r195367:
------------------------------------------------------------------------
r195367 | joey | 2013-11-21 09:09:05 -0800 (Thu, 21 Nov 2013) | 17 lines

Fix a crash in EmitStoreThroughExtVectorComponentLValue for vectors of odd sizes.

In OpenCL a vector of 3 elements, acts like a vector of four elements.
So for a vector of size 3 the '.hi' and '.odd' accessors, would access
the elements {2, 3} and {1, 3} respectively.
However, in EmitStoreThroughExtVectorComponentLValue we are still operating on
a vector of size 3, so we should only access {2} and {1}. We do this by checking
the last element to be accessed, and ignore it if it is out-of-bounds.

EmitLoadOfExtVectorElementLValue doesn't have a similar problem, because it does
a direct shufflevector with undef, so an out-of-bounds access just gives an undef
value.

Patch by Anastasia Stulova!



------------------------------------------------------------------------

llvm-svn: 195386
2013-11-21 23:33:07 +00:00
Bill Wendling
e8bc90c5e4 Merging r195268:
------------------------------------------------------------------------
r195268 | jholewinski | 2013-11-20 12:35:34 -0800 (Wed, 20 Nov 2013) | 3 lines

[NVPTX] Update ABI handling

For PTX, we want the target to handle struct returns directly.
------------------------------------------------------------------------

llvm-svn: 195385
2013-11-21 23:31:45 +00:00
Bill Wendling
1ecd2e5da7 Merging r195339:
------------------------------------------------------------------------
r195339 | chapuni | 2013-11-21 02:55:15 -0800 (Thu, 21 Nov 2013) | 5 lines

Revert r195317 (and r195333), "Teach ISel not to optimize 'optnone' functions."

It broke, at least, i686 target. It is reproducible with "llc -mtriple=i686-unknown".

FYI, it didn't appear to add either "-O0" or "-fast-isel".
------------------------------------------------------------------------

llvm-svn: 195375
2013-11-21 20:18:40 +00:00
Bill Wendling
4969ad7578 Merging r195333:
------------------------------------------------------------------------
r195333 | kcc | 2013-11-21 01:28:16 -0800 (Thu, 21 Nov 2013) | 1 line

add 'REQUIRES: asserts' to a test that uses 'llc -debug'; this fixes the no-asserts build
------------------------------------------------------------------------

llvm-svn: 195374
2013-11-21 20:06:33 +00:00
Bill Wendling
147d8d00dd Add blurb about WebCL Validator.
llvm-svn: 195373
2013-11-21 19:58:50 +00:00
Daniel Sanders
fa963ed474 Merging r195355:
------------------------------------------------------------------------
r195355 | dsanders | 2013-11-21 13:24:49 +0000 (Thu, 21 Nov 2013) | 20 lines

Add support for legalizing SETNE/SETEQ by inverting the condition code and the result of the comparison.

Summary:
LegalizeSetCCCondCode can now legalize SETEQ and SETNE by returning the inverse
condition and requesting that the caller invert the result of the condition.

The caller of LegalizeSetCCCondCode must handle the inverted CC, and they do
so as follows:
  SETCC, BR_CC:
    Invert the result of the SETCC with SelectionDAG::getNOT()
  SELECT_CC:
    Swap the true/false operands.

This is necessary for MSA which lacks an integer SETNE instruction.

Reviewers: resistor

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D2229
------------------------------------------------------------------------

llvm-svn: 195363
2013-11-21 15:03:54 +00:00
Tobias Grosser
0fa47bf8d8 cmake: Add option POLLY_USE_CLOOG
This allows to build Polly without CLooG.

llvm-svn: 195348
2013-11-21 11:51:46 +00:00
Sylvestre Ledru
f64d3a8260 [OCaml] Unbreak make install by providing ocamldoc target
Cherry-pick of Peter Zotov's commit in trunk (r195336)

llvm-svn: 195337
2013-11-21 10:20:23 +00:00
Bill Wendling
968096afc3 Merging r195317:
------------------------------------------------------------------------
r195317 | probinson | 2013-11-20 22:33:32 -0800 (Wed, 20 Nov 2013) | 4 lines

Teach ISel not to optimize 'optnone' functions.

Based on work by Andrea Di Biagio.

------------------------------------------------------------------------

llvm-svn: 195321
2013-11-21 07:11:48 +00:00
Bill Wendling
a9ae7d28c2 Merging r195272:
------------------------------------------------------------------------
r195272 | hfinkel | 2013-11-20 12:54:55 -0800 (Wed, 20 Nov 2013) | 4 lines

PPC popcnt[dw] do not have record forms

The instruction definitions incorrectly specified that popcntd and popcntw have
record forms; they do not. This mistake was causing invalid code generation.
------------------------------------------------------------------------

llvm-svn: 195320
2013-11-21 07:07:01 +00:00
Bill Wendling
d9c85bb743 Merging r195318:
------------------------------------------------------------------------
r195318 | void | 2013-11-20 23:04:30 -0800 (Wed, 20 Nov 2013) | 29 lines

The basic problem is that some mainstream programs cannot deal with the way
clang optimizes tail calls, as in this example:

int foo(void);
int bar(void) {
 return foo();
}

where the call is transformed to:

  calll .L0$pb
.L0$pb:
  popl  %eax
.Ltmp0:
  addl  $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax
  movl  foo@GOT(%eax), %eax
  popl  %ebp
  jmpl  *%eax                   # TAILCALL

However, the GOT references must all be resolved at dlopen() time, and so this
approach cannot be used with lazy dynamic linking (e.g. using RTLD_LAZY), which
usually populates the PLT with stubs that perform the actual resolving.

This patch changes X86TargetLowering::LowerCall() to skip tail call
optimization, if the called function is a global or external symbol.

Patch by Dimitry Andric!

PR15086
------------------------------------------------------------------------

llvm-svn: 195319
2013-11-21 07:05:41 +00:00
Bill Wendling
f0fd050d69 Add blurb about Likely.
llvm-svn: 195315
2013-11-21 06:15:39 +00:00
Bill Wendling
c8086045e0 Merging r195283:
------------------------------------------------------------------------
r195283 | hans | 2013-11-20 16:15:56 -0800 (Wed, 20 Nov 2013) | 10 lines

[-cxx-abi microsoft] Emit linkonce_odr definitions for declarations of static data members with inline initializers (PR17689)

This makes Clang emit a linkonce_odr definition for 'val' in the code below,
to be compatible with MSVC-compiled code:

  struct Foo {
    static const int val = 1;
  };

Differential Revision: http://llvm-reviews.chandlerc.com/D2233
------------------------------------------------------------------------

llvm-svn: 195314
2013-11-21 05:19:27 +00:00
Bill Wendling
c9466465f8 Add blurb about DXR.
llvm-svn: 195313
2013-11-21 05:17:31 +00:00
Petar Jovanovic
490f7edc18 Merging r195157:
------------------------------------------------------------------------
r195157 | petarj | 2013-11-19 22:56:00 +0100 (Tue, 19 Nov 2013) | 8 lines

[mips] Resolve relocation for the stubs in MCJIT when load address is known

Instead of processing relocation for branch to stubs right away, emit a
modified relocation and add it to queue to be resolved later when final load
address is known.
This resolves seven MIPS MCJIT issues that were caused by missing relocation
fixups at the end.

------------------------------------------------------------------------

llvm-svn: 195291
2013-11-21 00:52:34 +00:00
Bill Wendling
ab9e81dffc Update to 3.4 release.
llvm-svn: 195234
2013-11-20 10:05:25 +00:00
Bill Wendling
ff6e4f1cd2 Update to the 3.4 release numbers.
llvm-svn: 195233
2013-11-20 10:00:30 +00:00
Bill Wendling
041ac8b23a Update to the 3.4 release numbers.
llvm-svn: 195232
2013-11-20 09:58:26 +00:00
Bill Wendling
83a6ac1ad0 Regenerate configure files with 3.4svn changed to 3.4.
llvm-svn: 195231
2013-11-20 09:55:44 +00:00
Bill Wendling
e8920495e5 Merging r195174:
------------------------------------------------------------------------
r195174 | zaks | 2013-11-19 16:11:42 -0800 (Tue, 19 Nov 2013) | 1 line

[analyzer] Fix an infinite recursion in region invalidation by adding block count to the BlockDataRegion.
------------------------------------------------------------------------

llvm-svn: 195228
2013-11-20 06:47:04 +00:00
Bill Wendling
8deccc4d41 Merging r195168:
------------------------------------------------------------------------
r195168 | rnk | 2013-11-19 15:23:00 -0800 (Tue, 19 Nov 2013) | 17 lines

Add a mangler entry point for TBAA rather than using RTTI directly

Summary:
RTTI is not yet implemented for the Microsoft C++ ABI and isn't expected
soon.  We could easily add the mangling, but the error is what prevents
us from silently miscompiling code that expects RTTI.

Instead, add a new mangleTypeName entry point that simply forwards to
mangleName or mangleType to produce a string that isn't part of the ABI.
Itanium can continue to use RTTI names to avoid unecessary test
breakage.

This also seems like the right design.  The fact that TBAA names happen
to be RTTI names is now an implementation detail of the mangler, rather
than part of TBAA.

Differential Revision: http://llvm-reviews.chandlerc.com/D2153
------------------------------------------------------------------------

llvm-svn: 195227
2013-11-20 06:46:42 +00:00
Bill Wendling
21daaf73aa Merging r195154:
------------------------------------------------------------------------
r195154 | rafael | 2013-11-19 13:07:04 -0800 (Tue, 19 Nov 2013) | 15 lines

Further fixes when thiscall is the default for methods.

The previous patches tried to deduce the correct function type. I now realize
this is not possible in general. Consider

class foo {
    template <typename T> static void bar(T v);
};
extern template void foo::bar(const void *);

We will only know that bar is static after a lookup, so we have to handle this
in the template instantiation code.

This patch reverts my previous two changes (but not the tests) and instead
handles the issue in DeduceTemplateArguments.
------------------------------------------------------------------------

llvm-svn: 195226
2013-11-20 06:45:19 +00:00
Bill Wendling
f2486aa0e6 Merging r195149:
------------------------------------------------------------------------
r195149 | grosbach | 2013-11-19 12:18:39 -0800 (Tue, 19 Nov 2013) | 6 lines

ARM: embedded v7 'darwin' doesn't get min-version defines.

Make sure armv7 doesn't get the iOS deployment version definitions when
it's being used for non-iOS.

rdar://15497681
------------------------------------------------------------------------

llvm-svn: 195225
2013-11-20 06:44:29 +00:00
Bill Wendling
a793dd3b19 Merging r195146:
------------------------------------------------------------------------
r195146 | fjahanian | 2013-11-19 11:26:30 -0800 (Tue, 19 Nov 2013) | 4 lines

ObjectiveC ARC. Removes a bogus warning when a weak 
property is redeclared as 'weak' in class extension.
// rdar://15465916

------------------------------------------------------------------------

llvm-svn: 195224
2013-11-20 06:43:12 +00:00
Bill Wendling
a18f634eb5 Merging r195143:
------------------------------------------------------------------------
r195143 | marshall | 2013-11-19 11:14:27 -0800 (Tue, 19 Nov 2013) | 1 line

Fix a test that I broke over the weekend
------------------------------------------------------------------------

llvm-svn: 195223
2013-11-20 06:40:42 +00:00
Bill Wendling
58ddea3a9f Merging r195162:
------------------------------------------------------------------------
r195162 | arnolds | 2013-11-19 14:20:20 -0800 (Tue, 19 Nov 2013) | 12 lines

SLPVectorizer: Fix stale for Value pointer array

We are slicing an array of Value pointers and process those slices in a loop.
The problem is that we might invalidate a later slice by vectorizing a former
slice.

Use a WeakVH to track the pointer. If the pointer is deleted or RAUW'ed we can
tell.

The test case will only fail when running with libgmalloc.

radar://15498655
------------------------------------------------------------------------

llvm-svn: 195222
2013-11-20 06:28:12 +00:00
Bill Wendling
8a9d4e8889 Merging r195161:
------------------------------------------------------------------------
r195161 | arnolds | 2013-11-19 14:20:18 -0800 (Tue, 19 Nov 2013) | 1 line

SLPVectorizer: Fix whitespace errors
------------------------------------------------------------------------

llvm-svn: 195221
2013-11-20 06:27:56 +00:00
Bill Wendling
a1c64cc979 Merging r195152:
------------------------------------------------------------------------
r195152 | jacksprat | 2013-11-19 12:53:28 -0800 (Tue, 19 Nov 2013) | 1 line

reverts 195057 per request
------------------------------------------------------------------------

llvm-svn: 195220
2013-11-20 06:21:08 +00:00
Bill Wendling
d8820a53ff Merging r195138:
------------------------------------------------------------------------
r195138 | atrick | 2013-11-19 10:29:45 -0800 (Tue, 19 Nov 2013) | 3 lines

Obvious pasto survived a couple rounds of cleanup.

Caught by Aaron Ballman.
------------------------------------------------------------------------

llvm-svn: 195219
2013-11-20 06:19:13 +00:00
Bill Wendling
7f6a31cda8 Merging r195129:
------------------------------------------------------------------------
r195129 | mcinally | 2013-11-19 06:36:00 -0800 (Tue, 19 Nov 2013) | 2 lines

Fix assembly operands for the SSE2 cvtsd2ss instruction.

------------------------------------------------------------------------

llvm-svn: 195218
2013-11-20 06:17:43 +00:00
Bill Wendling
9dcaf9211d Merging r195118:
------------------------------------------------------------------------
r195118 | chandlerc | 2013-11-19 01:03:18 -0800 (Tue, 19 Nov 2013) | 22 lines

Fix an issue where SROA computed different results based on the relative
order of slices of the alloca which have exactly the same size and other
properties. This was found by a perniciously unstable sort
implementation used to flush out buggy uses of the algorithm.

The fundamental idea is that findCommonType should return the best
common type it can find across all of the slices in the range. There
were two bugs here previously:

1) We would accept an integer type smaller than a byte-width multiple,
   and if there were different bit-width integer types, we would accept
   the first one. This caused an actual failure in the testcase updated
   here when the sort order changed.
2) If we found a bad combination of types or a non-load, non-store use
   before an integer typed load or store we would bail, but if we found
   the integere typed load or store, we would use it. The correct
   behavior is to always use an integer typed operation which covers the
   partition if one exists.

While a clever debugging sort algorithm found problem #1 in our existing
test cases, I have no useful test case ideas for #2. I spotted in by
inspection when looking at this code.
------------------------------------------------------------------------

llvm-svn: 195217
2013-11-20 06:15:56 +00:00
Bill Wendling
e6a6b76ef5 Merging r195102:
------------------------------------------------------------------------
r195102 | void | 2013-11-18 20:58:46 -0800 (Mon, 18 Nov 2013) | 1 line

Add lld to projects to tag.
------------------------------------------------------------------------

llvm-svn: 195195
2013-11-20 04:59:22 +00:00
Bill Wendling
3f48946bee Merging r195193:
------------------------------------------------------------------------
r195193 | void | 2013-11-19 20:55:20 -0800 (Tue, 19 Nov 2013) | 5 lines

Add -triple option.

The -triple option is used to create a named tarball of the release binaries.

Also disable the RPATH modifications on Mac OS X. It's not needed.
------------------------------------------------------------------------

llvm-svn: 195194
2013-11-20 04:56:36 +00:00
Bill Wendling
fcab280ff6 Merging r195158:
------------------------------------------------------------------------
r195158 | whunt | 2013-11-19 14:11:09 -0800 (Tue, 19 Nov 2013) | 9 lines

Microsoft Record Layout: zero sized base after base with vbtbl fix

Microsoft adds an extra byte of padding before laying out zero sized 
non-virtual bases if the non-virtual base before it contains a vbptr.  
This patch adds the same behavior to clang.

Differential Revision: http://llvm-reviews.chandlerc.com/D2106


------------------------------------------------------------------------

llvm-svn: 195167
2013-11-19 23:16:16 +00:00
Bill Wendling
a6a08e04e1 Merging r195163:
------------------------------------------------------------------------
r195163 | rsmith | 2013-11-19 14:47:36 -0800 (Tue, 19 Nov 2013) | 5 lines

PR9547: If we're parsing a simple-declaration that contains a tag definition,
and we see an ill-formed declarator that would probably be well-formed if the
tag definition were just missing a semicolon, use that as the diagnostic
instead of producing some other mysterious error.

------------------------------------------------------------------------

llvm-svn: 195165
2013-11-19 22:56:43 +00:00
Bill Wendling
4b546deebf Merging r195136:
------------------------------------------------------------------------

llvm-svn: 195142
2013-11-19 18:43:51 +00:00
Bill Wendling
21a7129570 Merging r195135:
------------------------------------------------------------------------
r195135 | fjahanian | 2013-11-19 09:42:25 -0800 (Tue, 19 Nov 2013) | 3 lines

bjectiveC. Use a uniform diagnostic for
'objc_bridge' attribute. // rdar://15454846.

------------------------------------------------------------------------

llvm-svn: 195141
2013-11-19 18:43:09 +00:00
Bill Wendling
1de95ce83d Merging r195128:
------------------------------------------------------------------------
r195128 | alexfh | 2013-11-19 06:30:44 -0800 (Tue, 19 Nov 2013) | 11 lines

Refactoring: replaced (*(I + x)) with I[x].

Summary: Pure refactoring, no semantic changes intended.

Reviewers: klimek

Reviewed By: klimek

CC: cfe-commits, klimek

Differential Revision: http://llvm-reviews.chandlerc.com/D2220
------------------------------------------------------------------------

llvm-svn: 195140
2013-11-19 18:42:00 +00:00
Bill Wendling
68813cd78b Merging r195126:
------------------------------------------------------------------------
r195126 | joerg | 2013-11-19 05:38:38 -0800 (Tue, 19 Nov 2013) | 2 lines

Revert r194540, it breaks various C++ programs.

------------------------------------------------------------------------

llvm-svn: 195139
2013-11-19 18:41:11 +00:00
Bill Wendling
9afea5975a Merging r195103:
------------------------------------------------------------------------
r195103 | atrick | 2013-11-18 21:05:43 -0800 (Mon, 18 Nov 2013) | 1 line

Fix patchpoint comments.
------------------------------------------------------------------------

llvm-svn: 195115
2013-11-19 06:43:35 +00:00
Bill Wendling
23a96ccc5d Merging r195100:
------------------------------------------------------------------------
r195100 | djasper | 2013-11-18 20:26:05 -0800 (Mon, 18 Nov 2013) | 6 lines

Add .clang-format without column limit to subdirectory tests/.

A column limit in the test folder can lead to trouble as the RUN, CHECK,
etc. comments can potentially be broken over multiple lines changing
their meaning. Without column limit, clang-format will simply keep the
test author's line breaks.
------------------------------------------------------------------------

llvm-svn: 195114
2013-11-19 06:39:18 +00:00
Bill Wendling
7773e9f439 Merging r195094:
------------------------------------------------------------------------
r195094 | atrick | 2013-11-18 19:29:59 -0800 (Mon, 18 Nov 2013) | 3 lines

Use symbolic operands in the patchpoint folding routine and fix a spilling bug.

Fixes <rdar://15487687> [JS] AnyRegCC argument ends up being spilled
------------------------------------------------------------------------

llvm-svn: 195113
2013-11-19 06:37:03 +00:00
Bill Wendling
22ffa6296c Merging r195093:
------------------------------------------------------------------------
r195093 | atrick | 2013-11-18 19:29:56 -0800 (Mon, 18 Nov 2013) | 4 lines

Add an abstraction to handle patchpoint operands.

Hard-coded operand indices were scattered throughout lowering stages
and layers. It was super bug prone.
------------------------------------------------------------------------

llvm-svn: 195112
2013-11-19 06:36:46 +00:00
Bill Wendling
8d13612af6 Merging r195092:
------------------------------------------------------------------------
r195092 | ributzka | 2013-11-18 19:08:35 -0800 (Mon, 18 Nov 2013) | 5 lines

[weak vtables] Place class definitions into anonymous namespaces to prevent weak vtables.

This patch places class definitions in implementation files into anonymous
namespaces to prevent weak vtables. This eliminates the need of providing an
out-of-line definition to pin the vtable explicitly to the file.
------------------------------------------------------------------------

llvm-svn: 195111
2013-11-19 06:35:35 +00:00
Bill Wendling
413a2d2642 Creating release_34 branch
llvm-svn: 195091
llvm-svn: 195090
llvm-svn: 195089
llvm-svn: 195088
llvm-svn: 195087
llvm-svn: 195086
llvm-svn: 195083
llvm-svn: 195082
2013-11-19 02:58:40 +00:00
26723 changed files with 913948 additions and 2067256 deletions

View File

@@ -1,4 +1,4 @@
{
"project_id" : "clang-tools-extra",
"conduit_uri" : "http://reviews.llvm.org/"
"conduit_uri" : "http://llvm-reviews.chandlerc.com/"
}

View File

@@ -1,20 +1,14 @@
check_library_exists(edit el_init "" HAVE_LIBEDIT)
add_subdirectory(clang-apply-replacements)
add_subdirectory(clang-modernize)
add_subdirectory(clang-rename)
add_subdirectory(modularize)
add_subdirectory(module-map-checker)
add_subdirectory(remove-cstr-calls)
if(CLANG_ENABLE_STATIC_ANALYZER)
add_subdirectory(clang-tidy)
endif()
add_subdirectory(clang-query)
add_subdirectory(clang-tidy)
add_subdirectory(modularize)
add_subdirectory(pp-trace)
add_subdirectory(remove-cstr-calls)
add_subdirectory(tool-template)
# Add the common testsuite after all the tools.
# TODO: Support tests with more granularity when features are off?
if(CLANG_ENABLE_STATIC_ANALYZER)
add_subdirectory(test)
add_subdirectory(unittests)
endif()

View File

@@ -4,7 +4,7 @@ LLVM Release License
University of Illinois/NCSA
Open Source License
Copyright (c) 2007-2014 University of Illinois at Urbana-Champaign.
Copyright (c) 2007-2013 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:

View File

@@ -11,10 +11,9 @@ CLANG_LEVEL := ../..
include $(CLANG_LEVEL)/../../Makefile.config
PARALLEL_DIRS := remove-cstr-calls tool-template modularize \
module-map-checker pp-trace
DIRS := clang-apply-replacements clang-modernize clang-rename clang-tidy \
clang-query unittests
PARALLEL_DIRS := remove-cstr-calls tool-template modularize pp-trace
DIRS := clang-apply-replacements clang-modernize clang-tidy clang-query \
unittests
include $(CLANG_LEVEL)/Makefile

View File

@@ -1,15 +1,19 @@
set(LLVM_LINK_COMPONENTS
Support
${LLVM_TARGETS_TO_BUILD}
asmparser
bitreader
support
mc
)
add_clang_library(clangApplyReplacements
lib/Tooling/ApplyReplacements.cpp
LINK_LIBS
clangAST
)
target_link_libraries(clangApplyReplacements
clangTooling
clangBasic
clangRewrite
clangToolingCore
clangRewriteFrontend
clangFormat
)
include_directories(

View File

@@ -19,9 +19,9 @@
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <system_error>
#include "llvm/Support/system_error.h"
#include <vector>
#include <string>
namespace clang {
@@ -45,9 +45,8 @@ TUReplacements;
typedef std::vector<std::string> TUReplacementFiles;
/// \brief Map mapping file name to Replacements targeting that file.
typedef llvm::DenseMap<const clang::FileEntry *,
std::vector<clang::tooling::Replacement>>
FileToReplacementsMap;
typedef llvm::StringMap<std::vector<clang::tooling::Replacement> >
FileToReplacementsMap;
/// \brief Recursively descends through a directory structure rooted at \p
/// Directory and attempts to deserialize *.yaml files as
@@ -66,7 +65,7 @@ typedef llvm::DenseMap<const clang::FileEntry *,
///
/// \returns An error_code indicating success or failure in navigating the
/// directory structure.
std::error_code
llvm::error_code
collectReplacementsFromDirectory(const llvm::StringRef Directory,
TUReplacements &TUs,
TUReplacementFiles &TURFiles,

View File

@@ -36,7 +36,7 @@ static void eatDiagnostics(const SMDiagnostic &, void *) {}
namespace clang {
namespace replace {
std::error_code
llvm::error_code
collectReplacementsFromDirectory(const llvm::StringRef Directory,
TUReplacements &TUs,
TUReplacementFiles & TURFiles,
@@ -44,7 +44,7 @@ collectReplacementsFromDirectory(const llvm::StringRef Directory,
using namespace llvm::sys::fs;
using namespace llvm::sys::path;
std::error_code ErrorCode;
error_code ErrorCode;
for (recursive_directory_iterator I(Directory, ErrorCode), E;
I != E && !ErrorCode; I.increment(ErrorCode)) {
@@ -59,15 +59,15 @@ collectReplacementsFromDirectory(const llvm::StringRef Directory,
TURFiles.push_back(I->path());
ErrorOr<std::unique_ptr<MemoryBuffer>> Out =
MemoryBuffer::getFile(I->path());
if (std::error_code BufferError = Out.getError()) {
OwningPtr<MemoryBuffer> Out;
error_code BufferError = MemoryBuffer::getFile(I->path(), Out);
if (BufferError) {
errs() << "Error reading " << I->path() << ": " << BufferError.message()
<< "\n";
continue;
}
yaml::Input YIn(Out.get()->getBuffer(), nullptr, &eatDiagnostics);
yaml::Input YIn(Out->getBuffer(), NULL, &eatDiagnostics);
tooling::TranslationUnitReplacements TU;
YIn >> TU;
if (YIn.error()) {
@@ -98,26 +98,29 @@ static void reportConflict(
// FIXME: Output something a little more user-friendly (e.g. unified diff?)
errs() << "The following changes conflict:\n";
for (const tooling::Replacement &R : ConflictingReplacements) {
if (R.getLength() == 0) {
errs() << " Insert at " << SM.getLineNumber(FID, R.getOffset()) << ":"
<< SM.getColumnNumber(FID, R.getOffset()) << " "
<< R.getReplacementText() << "\n";
for (const tooling::Replacement *I = ConflictingReplacements.begin(),
*E = ConflictingReplacements.end();
I != E; ++I) {
if (I->getLength() == 0) {
errs() << " Insert at " << SM.getLineNumber(FID, I->getOffset()) << ":"
<< SM.getColumnNumber(FID, I->getOffset()) << " "
<< I->getReplacementText() << "\n";
} else {
if (R.getReplacementText().empty())
if (I->getReplacementText().empty())
errs() << " Remove ";
else
errs() << " Replace ";
errs() << SM.getLineNumber(FID, R.getOffset()) << ":"
<< SM.getColumnNumber(FID, R.getOffset()) << "-"
<< SM.getLineNumber(FID, R.getOffset() + R.getLength() - 1) << ":"
<< SM.getColumnNumber(FID, R.getOffset() + R.getLength() - 1);
errs() << SM.getLineNumber(FID, I->getOffset()) << ":"
<< SM.getColumnNumber(FID, I->getOffset()) << "-"
<< SM.getLineNumber(FID, I->getOffset() + I->getLength() - 1)
<< ":"
<< SM.getColumnNumber(FID, I->getOffset() + I->getLength() - 1);
if (R.getReplacementText().empty())
if (I->getReplacementText().empty())
errs() << "\n";
else
errs() << " with \"" << R.getReplacementText() << "\"\n";
errs() << " with \"" << I->getReplacementText() << "\"\n";
}
}
}
@@ -137,24 +140,33 @@ static bool deduplicateAndDetectConflicts(FileToReplacementsMap &Replacements,
SourceManager &SM) {
bool conflictsFound = false;
for (auto &FileAndReplacements : Replacements) {
const FileEntry *Entry = FileAndReplacements.first;
auto &Replacements = FileAndReplacements.second;
assert(Entry != nullptr && "No file entry!");
for (FileToReplacementsMap::iterator I = Replacements.begin(),
E = Replacements.end();
I != E; ++I) {
const FileEntry *Entry = SM.getFileManager().getFile(I->getKey());
if (!Entry) {
errs() << "Described file '" << I->getKey()
<< "' doesn't exist. Ignoring...\n";
continue;
}
std::vector<tooling::Range> Conflicts;
tooling::deduplicate(FileAndReplacements.second, Conflicts);
tooling::deduplicate(I->getValue(), Conflicts);
if (Conflicts.empty())
continue;
conflictsFound = true;
errs() << "There are conflicting changes to " << Entry->getName() << ":\n";
errs() << "There are conflicting changes to " << I->getKey() << ":\n";
for (const tooling::Range &Conflict : Conflicts) {
auto ConflictingReplacements = llvm::makeArrayRef(
&Replacements[Conflict.getOffset()], Conflict.getLength());
for (std::vector<tooling::Range>::const_iterator
ConflictI = Conflicts.begin(),
ConflictE = Conflicts.end();
ConflictI != ConflictE; ++ConflictI) {
ArrayRef<tooling::Replacement> ConflictingReplacements(
&I->getValue()[ConflictI->getOffset()], ConflictI->getLength());
reportConflict(Entry, ConflictingReplacements, SM);
}
}
@@ -167,20 +179,14 @@ bool mergeAndDeduplicate(const TUReplacements &TUs,
clang::SourceManager &SM) {
// Group all replacements by target file.
std::set<StringRef> Warned;
for (const auto &TU : TUs) {
for (const tooling::Replacement &R : TU.Replacements) {
// Use the file manager to deduplicate paths. FileEntries are
// automatically canonicalized.
const FileEntry *Entry = SM.getFileManager().getFile(R.getFilePath());
if (!Entry && Warned.insert(R.getFilePath()).second) {
errs() << "Described file '" << R.getFilePath()
<< "' doesn't exist. Ignoring...\n";
continue;
}
GroupedReplacements[Entry].push_back(R);
}
}
for (TUReplacements::const_iterator TUI = TUs.begin(), TUE = TUs.end();
TUI != TUE; ++TUI)
for (std::vector<tooling::Replacement>::const_iterator
RI = TUI->Replacements.begin(),
RE = TUI->Replacements.end();
RI != RE; ++RI)
GroupedReplacements[RI->getFilePath()].push_back(*RI);
// Ask clang to deduplicate and report conflicts.
if (deduplicateAndDetectConflicts(GroupedReplacements, SM))
@@ -198,8 +204,10 @@ bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
// data structure for applying replacements. Rewriter certainly doesn't care.
// However, until we nail down the design of ReplacementGroups, might as well
// leave this as is.
for (const auto &FileAndReplacements : GroupedReplacements) {
if (!tooling::applyAllReplacements(FileAndReplacements.second, Rewrites))
for (FileToReplacementsMap::const_iterator I = GroupedReplacements.begin(),
E = GroupedReplacements.end();
I != E; ++I) {
if (!tooling::applyAllReplacements(I->getValue(), Rewrites))
return false;
}
@@ -215,7 +223,11 @@ RangeVector calculateChangedRanges(
// NOTE: This is O(n^2) in the number of replacements. If this starts to
// become a problem inline shiftedCodePosition() here and do shifts in a
// single run through this loop.
for (const tooling::Replacement &R : Replaces) {
for (std::vector<clang::tooling::Replacement>::const_iterator
I = Replaces.begin(),
E = Replaces.end();
I != E; ++I) {
const tooling::Replacement &R = *I;
unsigned Offset = tooling::shiftedCodePosition(Replaces, R.getOffset());
unsigned Length = R.getReplacementText().size();
@@ -233,10 +245,11 @@ bool writeFiles(const clang::Rewriter &Rewrites) {
const char *FileName =
Rewrites.getSourceMgr().getFileEntryForID(BufferI->first)->getName();
std::error_code EC;
llvm::raw_fd_ostream FileStream(FileName, EC, llvm::sys::fs::F_Text);
if (EC) {
errs() << "Warning: Could not write to " << EC.message() << "\n";
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(FileName, ErrorInfo);
if (!ErrorInfo.empty()) {
errs() << "Warning: Could not write to " << FileName << "\n";
continue;
}
BufferI->second.write(FileStream);
@@ -248,12 +261,13 @@ bool writeFiles(const clang::Rewriter &Rewrites) {
bool deleteReplacementFiles(const TUReplacementFiles &Files,
clang::DiagnosticsEngine &Diagnostics) {
bool Success = true;
for (const auto &Filename : Files) {
std::error_code Error = llvm::sys::fs::remove(Filename);
for (TUReplacementFiles::const_iterator I = Files.begin(), E = Files.end();
I != E; ++I) {
error_code Error = llvm::sys::fs::remove(*I);
if (Error) {
Success = false;
// FIXME: Use Diagnostics for outputting errors.
errs() << "Error deleting file: " << Filename << "\n";
errs() << "Error deleting file: " << *I << "\n";
errs() << Error.message() << "\n";
errs() << "Please delete the file manually\n";
}

View File

@@ -1,5 +1,9 @@
set(LLVM_LINK_COMPONENTS
Support
${LLVM_TARGETS_TO_BUILD}
asmparser
bitreader
support
mc
)
add_clang_executable(clang-apply-replacements
@@ -7,10 +11,6 @@ add_clang_executable(clang-apply-replacements
)
target_link_libraries(clang-apply-replacements
clangApplyReplacements
clangBasic
clangFormat
clangRewrite
clangToolingCore
)
install(TARGETS clang-apply-replacements

View File

@@ -199,10 +199,11 @@ int main(int argc, char **argv) {
// Only include our options in -help output.
StringMap<cl::Option*> OptMap;
cl::getRegisteredOptions(OptMap);
const char **EndOpts = std::end(OptionsToShow);
for (const auto &Opt : OptMap) {
if (std::find(OptionsToShow, EndOpts, Opt.getKey()) == EndOpts)
Opt.getValue()->setHiddenFlag(cl::ReallyHidden);
const char **EndOpts = OptionsToShow + array_lengthof(OptionsToShow);
for (StringMap<cl::Option *>::iterator I = OptMap.begin(), E = OptMap.end();
I != E; ++I) {
if (std::find(OptionsToShow, EndOpts, I->getKey()) == EndOpts)
I->getValue()->setHiddenFlag(cl::ReallyHidden);
}
cl::SetVersionPrinter(&printVersion);
@@ -211,17 +212,17 @@ int main(int argc, char **argv) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
DiagOpts.get());
DiagOpts.getPtr());
// Determine a formatting style from options.
format::FormatStyle FormatStyle;
if (DoFormat)
FormatStyle = format::getStyle(FormatStyleOpt, FormatStyleConfig, "LLVM");
FormatStyle = format::getStyle(FormatStyleOpt, FormatStyleConfig);
TUReplacements TUs;
TUReplacementFiles TURFiles;
std::error_code ErrorCode =
error_code ErrorCode =
collectReplacementsFromDirectory(Directory, TUs, TURFiles, Diagnostics);
if (ErrorCode) {
@@ -232,7 +233,7 @@ int main(int argc, char **argv) {
// Remove the TUReplacementFiles (triggered by "remove-change-desc-files"
// command line option) when exiting main().
std::unique_ptr<ScopedFileRemover> Remover;
OwningPtr<ScopedFileRemover> Remover;
if (RemoveTUReplacementFiles)
Remover.reset(new ScopedFileRemover(TURFiles, Diagnostics));
@@ -245,34 +246,35 @@ int main(int argc, char **argv) {
Rewriter ReplacementsRewriter(SM, LangOptions());
for (const auto &FileAndReplacements : GroupedReplacements) {
// This shouldn't happen but if a file somehow has no replacements skip to
// next file.
if (FileAndReplacements.second.empty())
continue;
for (FileToReplacementsMap::const_iterator I = GroupedReplacements.begin(),
E = GroupedReplacements.end();
I != E; ++I) {
std::string NewFileData;
const char *FileName = FileAndReplacements.first->getName();
if (!applyReplacements(FileAndReplacements.second, NewFileData,
Diagnostics)) {
errs() << "Failed to apply replacements to " << FileName << "\n";
// This shouldn't happen but if a file somehow has no replacements skip to
// next file.
if (I->getValue().empty())
continue;
if (!applyReplacements(I->getValue(), NewFileData, Diagnostics)) {
errs() << "Failed to apply replacements to " << I->getKey() << "\n";
continue;
}
// Apply formatting if requested.
if (DoFormat &&
!applyFormatting(FileAndReplacements.second, NewFileData, NewFileData,
FormatStyle, Diagnostics)) {
errs() << "Failed to apply reformatting replacements for " << FileName
if (DoFormat && !applyFormatting(I->getValue(), NewFileData, NewFileData,
FormatStyle, Diagnostics)) {
errs() << "Failed to apply reformatting replacements for " << I->getKey()
<< "\n";
continue;
}
// Write new file to disk
std::error_code EC;
llvm::raw_fd_ostream FileStream(FileName, EC, llvm::sys::fs::F_None);
if (EC) {
llvm::errs() << "Could not open " << FileName << " for writing\n";
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(I->getKey().str().c_str(), ErrorInfo);
if (!ErrorInfo.empty()) {
llvm::errs() << "Could not open " << I->getKey() << " for writing\n";
continue;
}

View File

@@ -18,10 +18,9 @@ TOOL_NO_EXPORTS = 1
SOURCES = ClangApplyReplacementsMain.cpp
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc mcparser option
USEDLIBS = clangApplyReplacements.a clangFormat.a \
clangTooling.a clangToolingCore.a clangFrontend.a \
USEDLIBS = clangApplyReplacements.a clangFormat.a clangTooling.a clangFrontend.a \
clangSerialization.a clangDriver.a clangRewriteFrontend.a \
clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \
clangRewriteCore.a clangParse.a clangSema.a clangAnalysis.a \
clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@@ -16,6 +16,7 @@
#include "AddOverride.h"
#include "AddOverrideActions.h"
#include "AddOverrideMatchers.h"
#include "clang/Frontend/CompilerInstance.h"
using clang::ast_matchers::MatchFinder;
@@ -40,7 +41,7 @@ int AddOverrideTransform::apply(const CompilationDatabase &Database,
// Make Fixer available to handleBeginSource().
this->Fixer = &Fixer;
if (int result = AddOverrideTool.run(createActionFactory(Finder).get())) {
if (int result = AddOverrideTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}
@@ -51,7 +52,7 @@ int AddOverrideTransform::apply(const CompilationDatabase &Database,
bool AddOverrideTransform::handleBeginSource(clang::CompilerInstance &CI,
llvm::StringRef Filename) {
assert(Fixer != nullptr && "Fixer must be set");
assert(Fixer != NULL && "Fixer must be set");
Fixer->setPreprocessor(CI.getPreprocessor());
return Transform::handleBeginSource(CI, Filename);
}
@@ -69,7 +70,7 @@ struct AddOverrideFactory : TransformFactory {
}
}
Transform *createTransform(const TransformOptions &Opts) override {
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
return new AddOverrideTransform(Opts);
}
};

View File

@@ -32,10 +32,10 @@ public:
/// \see Transform::run().
virtual int apply(const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) override;
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
virtual bool handleBeginSource(clang::CompilerInstance &CI,
llvm::StringRef Filename) override;
llvm::StringRef Filename) LLVM_OVERRIDE;
private:
AddOverrideFixer *Fixer;

View File

@@ -16,10 +16,11 @@
#include "AddOverrideActions.h"
#include "AddOverrideMatchers.h"
#include "Core/Transform.h"
#include "clang/Basic/CharInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
@@ -88,7 +89,7 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) {
std::string ReplacementText = " override";
if (DetectMacros) {
assert(PP && "No access to Preprocessor object for macro detection");
assert(PP != 0 && "No access to Preprocessor object for macro detection");
clang::TokenValue Tokens[] = { PP->getIdentifierInfo("override") };
llvm::StringRef MacroName = PP->getLastMacroWithSpelling(StartLoc, Tokens);
if (!MacroName.empty())

View File

@@ -7,13 +7,11 @@ add_clang_library(modernizeCore
IncludeExcludeInfo.cpp
PerfSupport.cpp
IncludeDirectives.cpp
LINK_LIBS
clangAST
clangASTMatchers
clangBasic
clangFrontend
clangLex
clangTooling
clangToolingCore
)
target_link_libraries(modernizeCore
clangFormat
clangTooling
clangBasic
clangASTMatchers
clangRewriteFrontend
)

View File

@@ -32,7 +32,7 @@ class IncludeDirectivesPPCallback : public clang::PPCallbacks {
// Struct helping the detection of header guards in the various callbacks
struct GuardDetection {
GuardDetection(FileID FID)
: FID(FID), Count(0), TheMacro(nullptr), CountAtEndif(0) {}
: FID(FID), Count(0), TheMacro(0), CountAtEndif(0) {}
FileID FID;
// count for relevant preprocessor directives
@@ -58,16 +58,15 @@ class IncludeDirectivesPPCallback : public clang::PPCallbacks {
};
public:
IncludeDirectivesPPCallback(IncludeDirectives *Self)
: Self(Self), Guard(nullptr) {}
virtual ~IncludeDirectivesPPCallback() {}
IncludeDirectivesPPCallback(IncludeDirectives *Self) : Self(Self), Guard(0) {}
private:
virtual ~IncludeDirectivesPPCallback() {}
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
const Module *Imported) override {
const Module *Imported) LLVM_OVERRIDE {
SourceManager &SM = Self->Sources;
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(HashLoc));
assert(FE && "Valid file expected.");
@@ -80,7 +79,7 @@ private:
// Keep track of the current file in the stack
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
FileID PrevFID) override {
FileID PrevFID) {
SourceManager &SM = Self->Sources;
switch (Reason) {
case EnterFile:
@@ -116,8 +115,7 @@ private:
// checking for equality because it can also be part of the preamble if the
// preamble is the whole file.
unsigned Preamble =
Lexer::ComputePreamble(SM.getBuffer(Guard.FID)->getBuffer(), LangOpts)
.first;
Lexer::ComputePreamble(SM.getBuffer(Guard.FID), LangOpts).first;
unsigned IfndefOffset = SM.getFileOffset(Guard.IfndefLoc);
if (IfndefOffset > (Preamble + 1))
return;
@@ -144,13 +142,13 @@ private:
}
virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) override {
const MacroDirective *MD) {
Guard->Count++;
// If this #ifndef is the top-most directive and the symbol isn't defined
// store those information in the guard detection, the next step will be to
// check for the define.
if (Guard->Count == 1 && MD == nullptr) {
if (Guard->Count == 1 && MD == 0) {
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
if (MII->hasMacroDefinition())
@@ -161,13 +159,13 @@ private:
}
virtual void MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) override {
const MacroDirective *MD) {
Guard->Count++;
// If this #define is the second directive of the file and the symbol
// defined is the same as the one checked in the #ifndef then store the
// information about this define.
if (Guard->Count == 2 && Guard->TheMacro != nullptr) {
if (Guard->Count == 2 && Guard->TheMacro != 0) {
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
// macro unrelated to the ifndef, doesn't look like a proper header guard
@@ -178,7 +176,7 @@ private:
}
}
void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
Guard->Count++;
// If it's the #endif corresponding to the top-most #ifndef
@@ -197,32 +195,23 @@ private:
}
virtual void MacroExpands(const Token &, const MacroDirective *, SourceRange,
const MacroArgs *) override {
const MacroArgs *) {
Guard->Count++;
}
virtual void MacroUndefined(const Token &,
const MacroDirective *) override {
virtual void MacroUndefined(const Token &, const MacroDirective *) {
Guard->Count++;
}
virtual void Defined(const Token &, const MacroDirective *,
SourceRange) override {
virtual void Defined(const Token &, const MacroDirective *, SourceRange) {
Guard->Count++;
}
virtual void If(SourceLocation, SourceRange,
ConditionValueKind) override {
virtual void If(SourceLocation, SourceRange, bool) { Guard->Count++; }
virtual void Elif(SourceLocation, SourceRange, bool, SourceLocation) {
Guard->Count++;
}
virtual void Elif(SourceLocation, SourceRange, ConditionValueKind,
SourceLocation) override {
Guard->Count++;
}
virtual void Ifdef(SourceLocation, const Token &,
const MacroDirective *) override {
Guard->Count++;
}
void Else(SourceLocation, SourceLocation) override {
virtual void Ifdef(SourceLocation, const Token &, const MacroDirective *) {
Guard->Count++;
}
virtual void Else(SourceLocation, SourceLocation) { Guard->Count++; }
IncludeDirectives *Self;
// keep track of the guard info through the include stack
@@ -311,8 +300,7 @@ static std::pair<unsigned, bool> findDirectiveEnd(SourceLocation HashLoc,
IncludeDirectives::IncludeDirectives(clang::CompilerInstance &CI)
: CI(CI), Sources(CI.getSourceManager()) {
// addPPCallbacks takes ownership of the callback
CI.getPreprocessor().addPPCallbacks(
llvm::make_unique<IncludeDirectivesPPCallback>(this));
CI.getPreprocessor().addPPCallbacks(new IncludeDirectivesPPCallback(this));
}
bool IncludeDirectives::lookForInclude(const FileEntry *File,
@@ -366,7 +354,7 @@ Replacement IncludeDirectives::addAngledInclude(const clang::FileEntry *File,
return Replacement();
unsigned Offset, NLFlags;
std::tie(Offset, NLFlags) = angledIncludeInsertionOffset(FID);
llvm::tie(Offset, NLFlags) = angledIncludeInsertionOffset(FID);
StringRef EOL = guessEOL(Sources, FID);
llvm::SmallString<32> InsertionText;

View File

@@ -19,8 +19,8 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <vector>
namespace clang {

View File

@@ -82,8 +82,8 @@ std::string removeRelativeOperators(StringRef Path) {
/// \brief Helper function to tokenize a string of paths and populate
/// the vector.
std::error_code parseCLInput(StringRef Line, std::vector<std::string> &List,
StringRef Separator) {
error_code parseCLInput(StringRef Line, std::vector<std::string> &List,
StringRef Separator) {
SmallVector<StringRef, 32> Tokens;
Line.split(Tokens, Separator, /*MaxSplit=*/ -1, /*KeepEmpty=*/ false);
for (SmallVectorImpl<StringRef>::iterator I = Tokens.begin(),
@@ -91,7 +91,7 @@ std::error_code parseCLInput(StringRef Line, std::vector<std::string> &List,
I != E; ++I) {
// Convert each path to its absolute path.
PathString Path = I->rtrim();
if (std::error_code Err = sys::fs::make_absolute(Path))
if (error_code Err = sys::fs::make_absolute(Path))
return Err;
// Remove relative operators from the path.
std::string AbsPath = removeRelativeOperators(Path);
@@ -103,50 +103,44 @@ std::error_code parseCLInput(StringRef Line, std::vector<std::string> &List,
llvm::errs() << "Parse: " <<List.back() << "\n";
}
return std::error_code();
return error_code::success();
}
} // end anonymous namespace
std::error_code
IncludeExcludeInfo::readListFromString(StringRef IncludeString,
StringRef ExcludeString) {
if (std::error_code Err = parseCLInput(IncludeString, IncludeList,
/*Separator=*/","))
error_code IncludeExcludeInfo::readListFromString(StringRef IncludeString,
StringRef ExcludeString) {
if (error_code Err = parseCLInput(IncludeString, IncludeList,
/*Separator=*/ ","))
return Err;
if (std::error_code Err = parseCLInput(ExcludeString, ExcludeList,
/*Separator=*/","))
if (error_code Err = parseCLInput(ExcludeString, ExcludeList,
/*Separator=*/ ","))
return Err;
return std::error_code();
return error_code::success();
}
std::error_code
IncludeExcludeInfo::readListFromFile(StringRef IncludeListFile,
StringRef ExcludeListFile) {
error_code IncludeExcludeInfo::readListFromFile(StringRef IncludeListFile,
StringRef ExcludeListFile) {
if (!IncludeListFile.empty()) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileBuf =
MemoryBuffer::getFile(IncludeListFile);
if (std::error_code Err = FileBuf.getError()) {
OwningPtr<MemoryBuffer> FileBuf;
if (error_code Err = MemoryBuffer::getFile(IncludeListFile, FileBuf)) {
errs() << "Unable to read from include file.\n";
return Err;
}
if (std::error_code Err =
parseCLInput(FileBuf.get()->getBuffer(), IncludeList,
/*Separator=*/"\n"))
if (error_code Err = parseCLInput(FileBuf->getBuffer(), IncludeList,
/*Separator=*/ "\n"))
return Err;
}
if (!ExcludeListFile.empty()) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileBuf =
MemoryBuffer::getFile(ExcludeListFile);
if (std::error_code Err = FileBuf.getError()) {
OwningPtr<MemoryBuffer> FileBuf;
if (error_code Err = MemoryBuffer::getFile(ExcludeListFile, FileBuf)) {
errs() << "Unable to read from exclude file.\n";
return Err;
}
if (std::error_code Err =
parseCLInput(FileBuf.get()->getBuffer(), ExcludeList,
/*Separator=*/"\n"))
if (error_code Err = parseCLInput(FileBuf->getBuffer(), ExcludeList,
/*Separator=*/ "\n"))
return Err;
}
return std::error_code();
return error_code::success();
}
bool IncludeExcludeInfo::isFileIncluded(StringRef FilePath) const {

View File

@@ -17,7 +17,7 @@
#define CLANG_MODERNIZE_INCLUDEEXCLUDEINFO_H
#include "llvm/ADT/StringRef.h"
#include <system_error>
#include "llvm/Support/system_error.h"
#include <vector>
/// \brief Class encapsulating the handling of include and exclude paths
@@ -29,16 +29,16 @@ public:
///
/// Returns error_code::success() on successful parse of the strings or
/// an error_code indicating the encountered error.
std::error_code readListFromString(llvm::StringRef IncludeString,
llvm::StringRef ExcludeString);
llvm::error_code readListFromString(llvm::StringRef IncludeString,
llvm::StringRef ExcludeString);
/// \brief Read and parse the lists of paths from \a IncludeListFile
/// and \a ExcludeListFile. Each file should contain one path per line.
///
/// Returns error_code::success() on successful read and parse of both files
/// or an error_code indicating the encountered error.
std::error_code readListFromFile(llvm::StringRef IncludeListFile,
llvm::StringRef ExcludeListFile);
llvm::error_code readListFromFile(llvm::StringRef IncludeListFile,
llvm::StringRef ExcludeListFile);
/// \brief Determine if the given path is in the list of include paths but
/// not in the list of exclude paths.

View File

@@ -15,9 +15,9 @@
#include "PerfSupport.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Path.h"
void collectSourcePerfData(const Transform &T, SourcePerfData &Data) {
for (Transform::TimingVec::const_iterator I = T.timing_begin(),
@@ -50,8 +50,8 @@ void writePerfDataJSON(
SS << DirectoryName << "/" << static_cast<int>(T.getWallTime()) << "_" << Pid
<< ".json";
std::error_code EC;
llvm::raw_fd_ostream FileStream(SS.str(), EC, llvm::sys::fs::F_Text);
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(SS.str().c_str(), ErrorInfo);
FileStream << "{\n";
FileStream << " \"Sources\" : [\n";
for (SourcePerfData::const_iterator I = TimingResults.begin(),

View File

@@ -18,6 +18,7 @@
#include "Transform.h"
#include "llvm/ADT/StringRef.h"
#include <map>
#include <vector>

View File

@@ -18,22 +18,21 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include <system_error>
#include "llvm/Support/system_error.h"
using namespace llvm;
using namespace llvm::sys;
using namespace clang::tooling;
bool ReplacementHandling::findClangApplyReplacements(const char *Argv0) {
ErrorOr<std::string> CARPathOrErr =
findProgramByName("clang-apply-replacements");
if (!CARPathOrErr)
CARPath = FindProgramByName("clang-apply-replacements");
if (!CARPath.empty())
return true;
CARPath = *CARPathOrErr;
static int StaticSymbol;
std::string ClangModernizePath = fs::getMainExecutable(Argv0, &StaticSymbol);
SmallString<128> TestPath = path::parent_path(ClangModernizePath);
CARPath = fs::getMainExecutable(Argv0, &StaticSymbol);
SmallString<128> TestPath = path::parent_path(CARPath);
path::append(TestPath, "clang-apply-replacements");
if (fs::can_execute(Twine(TestPath)))
CARPath = TestPath.str();
@@ -73,10 +72,11 @@ bool ReplacementHandling::serializeReplacements(
continue;
}
std::error_code EC;
raw_fd_ostream ReplacementsFile(ReplacementsFileName, EC, fs::F_None);
if (EC) {
errs() << "Error opening file: " << EC.message() << "\n";
std::string ErrorInfo;
raw_fd_ostream ReplacementsFile(ReplacementsFileName.c_str(), ErrorInfo,
fs::F_Binary);
if (!ErrorInfo.empty()) {
errs() << "Error opening file: " << ErrorInfo << "\n";
Errors = true;
continue;
}
@@ -101,12 +101,12 @@ bool ReplacementHandling::applyReplacements() {
Argv.push_back(DestinationDir.c_str());
// Argv array needs to be null terminated.
Argv.push_back(nullptr);
Argv.push_back(0);
std::string ErrorMsg;
bool ExecutionFailed = false;
int ReturnCode = ExecuteAndWait(CARPath.c_str(), Argv.data(),
/* env */ nullptr, /* redirects */ nullptr,
int ReturnCode = ExecuteAndWait(CARPath.c_str(), Argv.data(), /* env */ 0,
/* redirects */ 0,
/* secondsToWait */ 0, /* memoryLimit */ 0,
&ErrorMsg, &ExecutionFailed);
if (ExecutionFailed || !ErrorMsg.empty()) {
@@ -144,7 +144,7 @@ bool ReplacementHandling::generateReplacementsFileName(
Error.clear();
SmallString<128> Prefix = DestinationDir;
path::append(Prefix, path::filename(MainSourceFile));
if (std::error_code EC =
if (error_code EC =
fs::createUniqueFile(Prefix + "_%%_%%_%%_%%_%%_%%.yaml", Result)) {
const std::string &Msg = EC.message();
Error.append(Msg.begin(), Msg.end());

View File

@@ -16,8 +16,8 @@
#ifndef CLANG_MODERNIZE_REPLACEMENTHANDLING_H
#define CLANG_MODERNIZE_REPLACEMENTHANDLING_H
#include "Core/Transform.h"
#include "llvm/ADT/StringRef.h"
#include "Core/Transform.h"
class ReplacementHandling {
public:

View File

@@ -21,8 +21,6 @@
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
template class llvm::Registry<TransformFactory>;
using namespace clang;
llvm::cl::OptionCategory TransformsOptionsCategory("Transforms' options");
@@ -39,7 +37,7 @@ public:
ActionFactory(MatchFinder &Finder, Transform &Owner)
: Finder(Finder), Owner(Owner) {}
FrontendAction *create() override {
virtual FrontendAction *create() LLVM_OVERRIDE {
return new FactoryAdaptor(Finder, Owner);
}
@@ -49,20 +47,19 @@ private:
FactoryAdaptor(MatchFinder &Finder, Transform &Owner)
: Finder(Finder), Owner(Owner) {}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
StringRef) override {
ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) {
return Finder.newASTConsumer();
}
virtual bool BeginSourceFileAction(CompilerInstance &CI,
StringRef Filename) override {
StringRef Filename) LLVM_OVERRIDE {
if (!ASTFrontendAction::BeginSourceFileAction(CI, Filename))
return false;
return Owner.handleBeginSource(CI, Filename);
}
void EndSourceFileAction() override {
virtual void EndSourceFileAction() LLVM_OVERRIDE {
Owner.handleEndSource();
return ASTFrontendAction::EndSourceFileAction();
}
@@ -129,19 +126,18 @@ Transform::addReplacementForCurrentTU(const clang::tooling::Replacement &R) {
return true;
}
std::unique_ptr<FrontendActionFactory>
Transform::createActionFactory(MatchFinder &Finder) {
return llvm::make_unique<ActionFactory>(Finder, /*Owner=*/*this);
FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) {
return new ActionFactory(Finder, /*Owner=*/ *this);
}
Version Version::getFromString(llvm::StringRef VersionStr) {
llvm::StringRef MajorStr, MinorStr;
Version V;
std::tie(MajorStr, MinorStr) = VersionStr.split('.');
llvm::tie(MajorStr, MinorStr) = VersionStr.split('.');
if (!MinorStr.empty()) {
llvm::StringRef Ignore;
std::tie(MinorStr, Ignore) = MinorStr.split('.');
llvm::tie(MinorStr, Ignore) = MinorStr.split('.');
if (MinorStr.getAsInteger(10, V.Minor))
return Version();
}

View File

@@ -18,6 +18,7 @@
#include "Core/IncludeExcludeInfo.h"
#include "Core/Refactoring.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Registry.h"
#include "llvm/Support/Timer.h"
@@ -208,8 +209,8 @@ protected:
///
/// The factory returned by this function is responsible for calling back to
/// Transform to call handleBeginSource() and handleEndSource().
std::unique_ptr<clang::tooling::FrontendActionFactory>
createActionFactory(clang::ast_matchers::MatchFinder &Finder);
clang::tooling::FrontendActionFactory *
createActionFactory(clang::ast_matchers::MatchFinder &Finder);
private:
const std::string Name;
@@ -290,7 +291,7 @@ struct CompilerVersions {
/// Since.Msvc = Version(10);
/// }
///
/// Transform *createTransform(const TransformOptions &Opts) override {
/// Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
/// return new MyTransform(Opts);
/// }
/// };
@@ -322,6 +323,4 @@ protected:
typedef llvm::Registry<TransformFactory> TransformFactoryRegistry;
extern template class llvm::Registry<TransformFactory>;
#endif // CLANG_MODERNIZE_TRANSFORM_H

View File

@@ -61,7 +61,7 @@ Transforms::createSelectedTransforms(const TransformOptions &GlobalOptions,
if (!OptionEnabled)
continue;
std::unique_ptr<TransformFactory> Factory(I->instantiate());
llvm::OwningPtr<TransformFactory> Factory(I->instantiate());
if (Factory->supportsCompilers(RequiredVersions))
ChosenTransforms.push_back(Factory->createTransform(GlobalOptions));
else if (ExplicitlyEnabled)

View File

@@ -17,8 +17,9 @@
#ifndef CLANG_MODERNIZE_TRANSFORMS_H
#define CLANG_MODERNIZE_TRANSFORMS_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/StringRef.h"
#include <vector>
// Forward declarations

View File

@@ -73,9 +73,9 @@ class ForLoopIndexUseVisitor
Context(Context), IndexVar(IndexVar), EndVar(EndVar),
ContainerExpr(ContainerExpr), ArrayBoundExpr(ArrayBoundExpr),
ContainerNeedsDereference(ContainerNeedsDereference),
OnlyUsedAsIndex(true), AliasDecl(nullptr), ConfidenceLevel(RL_Safe),
NextStmtParent(nullptr), CurrStmtParent(nullptr),
ReplaceWithAliasUse(false), AliasFromForInit(false) {
OnlyUsedAsIndex(true), AliasDecl(NULL), ConfidenceLevel(RL_Safe),
NextStmtParent(NULL), CurrStmtParent(NULL), ReplaceWithAliasUse(false),
AliasFromForInit(false) {
if (ContainerExpr) {
addComponent(ContainerExpr);
llvm::FoldingSetNodeID ID;
@@ -208,7 +208,7 @@ static StringRef getStringFromRange(SourceManager &SourceMgr,
SourceRange Range) {
if (SourceMgr.getFileID(Range.getBegin()) !=
SourceMgr.getFileID(Range.getEnd()))
return nullptr;
return NULL;
CharSourceRange SourceChars(Range, true);
return Lexer::getSourceText(SourceChars, SourceMgr, LangOpts);
@@ -224,7 +224,7 @@ static const DeclRefExpr *getDeclRef(const Expr *E) {
static const VarDecl *getReferencedVariable(const Expr *E) {
if (const DeclRefExpr *DRE = getDeclRef(E))
return dyn_cast<VarDecl>(DRE->getDecl());
return nullptr;
return NULL;
}
/// \brief Returns true when the given expression is a member expression
@@ -277,14 +277,14 @@ static bool areSameExpr(ASTContext *Context, const Expr *First,
/// as being initialized from `v.begin()`
static const Expr *digThroughConstructors(const Expr *E) {
if (!E)
return nullptr;
return NULL;
E = E->IgnoreParenImpCasts();
if (const CXXConstructExpr *ConstructExpr = dyn_cast<CXXConstructExpr>(E)) {
// The initial constructor must take exactly one parameter, but base class
// and deferred constructors can take more.
if (ConstructExpr->getNumArgs() != 1 ||
ConstructExpr->getConstructionKind() != CXXConstructExpr::CK_Complete)
return nullptr;
return NULL;
E = ConstructExpr->getArg(0);
if (const MaterializeTemporaryExpr *Temp =
dyn_cast<MaterializeTemporaryExpr>(E))
@@ -298,13 +298,13 @@ static const Expr *digThroughConstructors(const Expr *E) {
/// operand. Otherwise, return NULL.
static const Expr *getDereferenceOperand(const Expr *E) {
if (const UnaryOperator *Uop = dyn_cast<UnaryOperator>(E))
return Uop->getOpcode() == UO_Deref ? Uop->getSubExpr() : nullptr;
return Uop->getOpcode() == UO_Deref ? Uop->getSubExpr() : NULL;
if (const CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(E))
return OpCall->getOperator() == OO_Star && OpCall->getNumArgs() == 1 ?
OpCall->getArg(0) : nullptr;
OpCall->getArg(0) : NULL;
return nullptr;
return NULL;
}
/// \brief Returns true when the Container contains an Expr equivalent to E.
@@ -450,16 +450,9 @@ static bool isAliasDecl(const Decl *TheDecl, const VarDecl *IndexVar) {
const CXXOperatorCallExpr *OpCall = cast<CXXOperatorCallExpr>(Init);
if (OpCall->getOperator() == OO_Star)
return isDereferenceOfOpCall(OpCall, IndexVar);
if (OpCall->getOperator() == OO_Subscript) {
assert(OpCall->getNumArgs() == 2);
return true;
}
break;
}
case Stmt::CXXMemberCallExprClass:
return true;
default:
break;
}
@@ -886,19 +879,19 @@ static const Expr *getContainerFromBeginEndCall(const Expr *Init, bool IsBegin,
const CXXMemberCallExpr *TheCall =
dyn_cast_or_null<CXXMemberCallExpr>(digThroughConstructors(Init));
if (!TheCall || TheCall->getNumArgs() != 0)
return nullptr;
return NULL;
const MemberExpr *Member = dyn_cast<MemberExpr>(TheCall->getCallee());
if (!Member)
return nullptr;
return NULL;
const std::string Name = Member->getMemberDecl()->getName();
const std::string TargetName = IsBegin ? "begin" : "end";
if (Name != TargetName)
return nullptr;
return NULL;
const Expr *SourceExpr = Member->getBase();
if (!SourceExpr)
return nullptr;
return NULL;
*IsArrow = Member->isArrow();
return SourceExpr;
@@ -919,7 +912,7 @@ static const Expr *findContainer(ASTContext *Context, const Expr *BeginExpr,
const Expr *BeginContainerExpr =
getContainerFromBeginEndCall(BeginExpr, /*IsBegin=*/true, &BeginIsArrow);
if (!BeginContainerExpr)
return nullptr;
return NULL;
const Expr *EndContainerExpr =
getContainerFromBeginEndCall(EndExpr, /*IsBegin=*/false, &EndIsArrow);
@@ -927,7 +920,7 @@ static const Expr *findContainer(ASTContext *Context, const Expr *BeginExpr,
// for (IteratorType It = Obj.begin(), E = Obj->end(); It != E; ++It) { }
if (!EndContainerExpr || BeginIsArrow != EndIsArrow ||
!areSameExpr(Context, EndContainerExpr, BeginContainerExpr))
return nullptr;
return NULL;
*ContainerNeedsDereference = BeginIsArrow;
return BeginContainerExpr;
@@ -1063,7 +1056,7 @@ void LoopFixer::run(const MatchFinder::MatchResult &Result) {
if (FixerKind != LFK_Array && !EndVar)
ConfidenceLevel.lowerTo(RL_Reasonable);
const Expr *ContainerExpr = nullptr;
const Expr *ContainerExpr = NULL;
bool DerefByValue = false;
bool DerefByConstRef = false;
bool ContainerNeedsDereference = false;
@@ -1079,9 +1072,9 @@ void LoopFixer::run(const MatchFinder::MatchResult &Result) {
const CXXMemberCallExpr *BeginCall =
Nodes.getNodeAs<CXXMemberCallExpr>(BeginCallName);
assert(BeginCall && "Bad Callback. No begin call expression.");
assert(BeginCall != 0 && "Bad Callback. No begin call expression.");
QualType CanonicalBeginType =
BeginCall->getMethodDecl()->getReturnType().getCanonicalType();
BeginCall->getMethodDecl()->getResultType().getCanonicalType();
if (CanonicalBeginType->isPointerType() &&
CanonicalInitVarType->isPointerType()) {
@@ -1098,7 +1091,7 @@ void LoopFixer::run(const MatchFinder::MatchResult &Result) {
return;
}
DerefByValue = Nodes.getNodeAs<QualType>(DerefByValueResultName) != nullptr;
DerefByValue = Nodes.getNodeAs<QualType>(DerefByValueResultName) != 0;
if (!DerefByValue) {
if (const QualType *DerefType =
Nodes.getNodeAs<QualType>(DerefByRefResultName)) {

View File

@@ -16,8 +16,8 @@
#ifndef CLANG_MODERNIZE_LOOP_ACTIONS_H
#define CLANG_MODERNIZE_LOOP_ACTIONS_H
#include "Core/Transform.h"
#include "StmtAncestor.h"
#include "Core/Transform.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -53,7 +53,7 @@ struct TUTrackingInfo {
/// \}
private:
std::unique_ptr<StmtAncestorASTVisitor> ParentFinder;
llvm::OwningPtr<StmtAncestorASTVisitor> ParentFinder;
StmtGeneratedVarNameMap GeneratedDecls;
ReplacedVarsMap ReplacedVars;
};

View File

@@ -48,7 +48,7 @@ int LoopConvertTransform::apply(const CompilationDatabase &Database,
LFK_PseudoArray, /*Owner=*/ *this);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
if (int result = LoopTool.run(createActionFactory(Finder).get())) {
if (int result = LoopTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}
@@ -77,7 +77,7 @@ struct LoopConvertFactory : TransformFactory {
Since.Msvc = Version(11);
}
Transform *createTransform(const TransformOptions &Opts) override {
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
return new LoopConvertTransform(Opts);
}
};

View File

@@ -18,7 +18,7 @@
#define CLANG_MODERNIZE_LOOP_CONVERT_H
#include "Core/Transform.h"
#include "llvm/Support/Compiler.h" // For override
#include "llvm/Support/Compiler.h" // For LLVM_OVERRIDE
// Forward decl for private implementation.
struct TUTrackingInfo;
@@ -32,12 +32,12 @@ public:
/// \see Transform::run().
virtual int apply(const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) override;
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
virtual bool handleBeginSource(clang::CompilerInstance &CI,
llvm::StringRef Filename) override;
llvm::StringRef Filename) LLVM_OVERRIDE;
private:
std::unique_ptr<TUTrackingInfo> TUInfo;
llvm::OwningPtr<TUTrackingInfo> TUInfo;
};
#endif // CLANG_MODERNIZE_LOOP_CONVERT_H

View File

@@ -68,7 +68,7 @@ bool DependencyFinderASTVisitor::VisitDeclRefExpr(DeclRefExpr *DeclRef) {
bool DependencyFinderASTVisitor::VisitVarDecl(VarDecl *V) {
const Stmt *Curr = DeclParents->lookup(V);
// First, see if the variable was declared within an inner scope of the loop.
while (Curr != nullptr) {
while (Curr != NULL) {
if (Curr == ContainingStmt) {
DependsOnInsideVariable = true;
return false;

View File

@@ -43,7 +43,7 @@ class StmtAncestorASTVisitor :
public clang::RecursiveASTVisitor<StmtAncestorASTVisitor> {
public:
StmtAncestorASTVisitor() {
StmtStack.push_back(nullptr);
StmtStack.push_back(NULL);
}
/// \brief Run the analysis on the TranslationUnitDecl.

View File

@@ -65,7 +65,7 @@ std::string VariableNamer::createIndexName() {
/// We also check to see if the same identifier was generated by this loop
/// converter in a loop nested within SourceStmt.
bool VariableNamer::declarationExists(StringRef Symbol) {
assert(Context != nullptr && "Expected an ASTContext");
assert(Context != 0 && "Expected an ASTContext");
IdentifierInfo &Ident = Context->Idents.get(Symbol);
// Check if the symbol is not an identifier (ie. is a keyword or alias).
@@ -77,7 +77,7 @@ bool VariableNamer::declarationExists(StringRef Symbol) {
return true;
// Determine if the symbol was generated in a parent context.
for (const Stmt *S = SourceStmt; S != nullptr; S = ReverseAST->lookup(S)) {
for (const Stmt *S = SourceStmt; S != NULL; S = ReverseAST->lookup(S)) {
StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S);
if (I != GeneratedDecls->end() && I->second == Symbol)
return true;

View File

@@ -35,7 +35,7 @@ int PassByValueTransform::apply(const tooling::CompilationDatabase &Database,
// make the replacer available to handleBeginSource()
this->Replacer = &Replacer;
if (Tool.run(createActionFactory(Finder).get())) {
if (Tool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return 1;
}
@@ -62,7 +62,7 @@ struct PassByValueFactory : TransformFactory {
Since.Msvc = Version(11);
}
Transform *createTransform(const TransformOptions &Opts) override {
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
return new PassByValueTransform(Opts);
}
};

View File

@@ -16,8 +16,8 @@
#ifndef CLANG_MODERNIZE_PASS_BY_VALUE_H
#define CLANG_MODERNIZE_PASS_BY_VALUE_H
#include "Core/IncludeDirectives.h"
#include "Core/Transform.h"
#include "Core/IncludeDirectives.h"
class ConstructorParamReplacer;
@@ -55,18 +55,18 @@ class ConstructorParamReplacer;
class PassByValueTransform : public Transform {
public:
PassByValueTransform(const TransformOptions &Options)
: Transform("PassByValue", Options), Replacer(nullptr) {}
: Transform("PassByValue", Options), Replacer(0) {}
/// \see Transform::apply().
virtual int apply(const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) override;
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
private:
/// \brief Setups the \c IncludeDirectives for the replacer.
virtual bool handleBeginSource(clang::CompilerInstance &CI,
llvm::StringRef Filename) override;
llvm::StringRef Filename) LLVM_OVERRIDE;
std::unique_ptr<IncludeDirectives> IncludeManager;
llvm::OwningPtr<IncludeDirectives> IncludeManager;
ConstructorParamReplacer *Replacer;
};

View File

@@ -14,9 +14,9 @@
//===----------------------------------------------------------------------===//
#include "PassByValueActions.h"
#include "PassByValueMatchers.h"
#include "Core/IncludeDirectives.h"
#include "Core/Transform.h"
#include "PassByValueMatchers.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"

View File

@@ -54,7 +54,7 @@ public:
ConstructorParamReplacer(unsigned &AcceptedChanges, unsigned &RejectedChanges,
Transform &Owner)
: AcceptedChanges(AcceptedChanges), RejectedChanges(RejectedChanges),
Owner(Owner), IncludeManager(nullptr) {}
Owner(Owner), IncludeManager(0) {}
void setIncludeDirectives(IncludeDirectives *Includes) {
IncludeManager = Includes;
@@ -63,7 +63,7 @@ public:
private:
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
override;
LLVM_OVERRIDE;
unsigned &AcceptedChanges;
unsigned &RejectedChanges;

View File

@@ -34,7 +34,7 @@ ReplaceAutoPtrTransform::apply(const CompilationDatabase &Database,
Finder.addMatcher(makeAutoPtrUsingDeclMatcher(), &Replacer);
Finder.addMatcher(makeTransferOwnershipExprMatcher(), &Fixer);
if (Tool.run(createActionFactory(Finder).get())) {
if (Tool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return 1;
}
@@ -52,7 +52,7 @@ struct ReplaceAutoPtrFactory : TransformFactory {
Since.Msvc = Version(11);
}
Transform *createTransform(const TransformOptions &Opts) override {
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
return new ReplaceAutoPtrTransform(Opts);
}
};

View File

@@ -48,7 +48,7 @@ public:
/// \see Transform::run().
virtual int apply(const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) override;
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
#endif // CLANG_MODERNIZE_REPLACE_AUTO_PTR_H

View File

@@ -14,8 +14,9 @@
//===----------------------------------------------------------------------===//
#include "ReplaceAutoPtrActions.h"
#include "Core/Transform.h"
#include "ReplaceAutoPtrMatchers.h"
#include "Core/Transform.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"

View File

@@ -30,7 +30,7 @@ public:
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
override;
LLVM_OVERRIDE;
private:
/// \brief Locates the \c auto_ptr token when it is referred by a \c TypeLoc.
@@ -89,7 +89,7 @@ public:
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
override;
LLVM_OVERRIDE;
private:
unsigned &AcceptedChanges;

View File

@@ -36,7 +36,7 @@ int UseAutoTransform::apply(const clang::tooling::CompilationDatabase &Database,
Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
if (int Result = UseAutoTool.run(createActionFactory(Finder).get())) {
if (int Result = UseAutoTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return Result;
}
@@ -54,7 +54,7 @@ struct UseAutoFactory : TransformFactory {
Since.Msvc = Version(10);
}
Transform *createTransform(const TransformOptions &Opts) override {
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
return new UseAutoTransform(Opts);
}
};

View File

@@ -35,7 +35,7 @@ public:
/// \see Transform::run().
virtual int apply(const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) override;
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
#endif // CLANG_MODERNIZE_USE_AUTO_H

View File

@@ -30,7 +30,7 @@ public:
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
override;
LLVM_OVERRIDE;
private:
unsigned &AcceptedChanges;
@@ -46,7 +46,7 @@ public:
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
override;
LLVM_OVERRIDE;
private:
unsigned &AcceptedChanges;

View File

@@ -16,8 +16,10 @@
#include "NullptrActions.h"
#include "NullptrMatchers.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Lex/Lexer.h"
@@ -151,7 +153,7 @@ public:
unsigned &AcceptedChanges, Transform &Owner)
: SM(Context.getSourceManager()), Context(Context),
UserNullMacros(UserNullMacros), AcceptedChanges(AcceptedChanges),
Owner(Owner), FirstSubExpr(nullptr), PruneSubtree(false) {}
Owner(Owner), FirstSubExpr(0), PruneSubtree(false) {}
bool TraverseStmt(Stmt *S) {
// Stop traversing down the tree if requested.
@@ -167,7 +169,7 @@ public:
bool VisitStmt(Stmt *S) {
CastExpr *C = dyn_cast<CastExpr>(S);
if (!C) {
FirstSubExpr = nullptr;
FirstSubExpr = 0;
return true;
} else if (!FirstSubExpr) {
FirstSubExpr = C->getSubExpr()->IgnoreParens();
@@ -383,27 +385,27 @@ private:
assert(MacroLoc.isFileID());
do {
const auto &Parents = Context.getParents(Start);
ASTContext::ParentVector Parents = Context.getParents(Start);
if (Parents.empty())
return false;
assert(Parents.size() == 1 &&
"Found an ancestor with more than one parent!");
const ast_type_traits::DynTypedNode &Parent = Parents[0];
ASTContext::ParentVector::const_iterator I = Parents.begin();
SourceLocation Loc;
if (const Decl *D = Parent.get<Decl>())
if (const Decl *D = I->get<Decl>())
Loc = D->getLocStart();
else if (const Stmt *S = Parent.get<Stmt>())
else if (const Stmt *S = I->get<Stmt>())
Loc = S->getLocStart();
else
llvm_unreachable("Expected to find Decl or Stmt containing ancestor");
if (!expandsFrom(Loc, MacroLoc)) {
Result = Parent;
Result = *I;
return true;
}
Start = Parent;
Start = *I;
} while (1);
llvm_unreachable("findContainingAncestor");

View File

@@ -46,7 +46,8 @@ int UseNullptrTransform::apply(const CompilationDatabase &Database,
NullptrFixer Fixer(AcceptedChanges, MacroNames, /*Owner=*/ *this);
Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
if (int result = UseNullptrTool.run(createActionFactory(Finder).get())) {
if (int result = UseNullptrTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}
@@ -64,7 +65,7 @@ struct UseNullptrFactory : TransformFactory {
Since.Msvc = Version(10);
}
Transform *createTransform(const TransformOptions &Opts) override {
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
return new UseNullptrTransform(Opts);
}
};

View File

@@ -18,7 +18,7 @@
#define CLANG_MODERNIZE_USE_NULLPTR_H
#include "Core/Transform.h"
#include "llvm/Support/Compiler.h" // For override
#include "llvm/Support/Compiler.h" // For LLVM_OVERRIDE
/// \brief Subclass of Transform that transforms null pointer constants into
/// C++11's nullptr keyword where possible.
@@ -29,7 +29,7 @@ public:
/// \see Transform::run().
virtual int apply(const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) override;
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
};
#endif // CLANG_MODERNIZE_USE_NULLPTR_H

View File

@@ -34,14 +34,6 @@ add_dependencies(clang-modernize
)
target_link_libraries(clang-modernize
clangAST
clangASTMatchers
clangBasic
clangFormat
clangFrontend
clangLex
clangTooling
clangToolingCore
modernizeCore
)

View File

@@ -213,13 +213,13 @@ static CompilerVersions handleSupportedCompilers(const char *ProgName,
E = Compilers.end();
I != E; ++I) {
llvm::StringRef Compiler, VersionStr;
std::tie(Compiler, VersionStr) = I->split('-');
llvm::tie(Compiler, VersionStr) = I->split('-');
Version *V = llvm::StringSwitch<Version *>(Compiler)
.Case("clang", &RequiredVersions.Clang)
.Case("gcc", &RequiredVersions.Gcc).Case("icc", &RequiredVersions.Icc)
.Case("msvc", &RequiredVersions.Msvc).Default(nullptr);
.Case("msvc", &RequiredVersions.Msvc).Default(NULL);
if (V == nullptr) {
if (V == NULL) {
llvm::errs() << ProgName << ": " << Compiler
<< ": unsupported platform\n";
Error = true;
@@ -248,15 +248,14 @@ static CompilerVersions handleSupportedCompilers(const char *ProgName,
return RequiredVersions;
}
std::unique_ptr<CompilationDatabase>
autoDetectCompilations(std::string &ErrorMessage) {
CompilationDatabase *autoDetectCompilations(std::string &ErrorMessage) {
// Auto-detect a compilation database from BuildPath.
if (BuildPath.getNumOccurrences() > 0)
return CompilationDatabase::autoDetectFromDirectory(BuildPath,
ErrorMessage);
// Try to auto-detect a compilation database from the first source.
if (!SourcePaths.empty()) {
if (std::unique_ptr<CompilationDatabase> Compilations =
if (CompilationDatabase *Compilations =
CompilationDatabase::autoDetectFromSource(SourcePaths[0],
ErrorMessage)) {
// FIXME: just pass SourcePaths[0] once getCompileCommands supports
@@ -276,11 +275,11 @@ autoDetectCompilations(std::string &ErrorMessage) {
// If no compilation database can be detected from source then we create a
// fixed compilation database with c++11 support.
std::string CommandLine[] = { "-std=c++11" };
return llvm::make_unique<FixedCompilationDatabase>(".", CommandLine);
return new FixedCompilationDatabase(".", CommandLine);
}
ErrorMessage = "Could not determine sources to transform";
return nullptr;
return 0;
}
// Predicate definition for determining whether a file is not included.
@@ -324,7 +323,7 @@ int main(int argc, const char **argv) {
cl::SetVersionPrinter(&printVersion);
// Parse options and generate compilations.
std::unique_ptr<CompilationDatabase> Compilations(
OwningPtr<CompilationDatabase> Compilations(
FixedCompilationDatabase::loadFromCommandLine(argc, argv));
cl::ParseCommandLineOptions(argc, argv);
@@ -335,7 +334,7 @@ int main(int argc, const char **argv) {
if (!Compilations) {
std::string ErrorMessage;
Compilations = autoDetectCompilations(ErrorMessage);
Compilations.reset(autoDetectCompilations(ErrorMessage));
if (!Compilations) {
llvm::errs() << llvm::sys::path::filename(argv[0]) << ": " << ErrorMessage
<< "\n";
@@ -396,7 +395,7 @@ int main(int argc, const char **argv) {
new DiagnosticOptions());
DiagnosticsEngine Diagnostics(
llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
DiagOpts.get());
DiagOpts.getPtr());
// FIXME: Make this DiagnosticsEngine available to all Transforms probably via
// GlobalOptions.
@@ -470,7 +469,7 @@ int main(int argc, const char **argv) {
if (FinalSyntaxCheck) {
ClangTool SyntaxTool(*Compilations, SourcePaths);
if (SyntaxTool.run(newFrontendActionFactory<SyntaxOnlyAction>().get()) != 0)
if (SyntaxTool.run(newFrontendActionFactory<SyntaxOnlyAction>()) != 0)
return 1;
}

View File

@@ -36,10 +36,9 @@ SOURCES += $(addprefix ../ReplaceAutoPtr/,$(notdir $(wildcard $(PROJ_SRC_DIR)/..
BUILT_SOURCES += $(ObjDir)/../ReplaceAutoPtr/.objdir
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc mcparser option
USEDLIBS = modernizeCore.a clangFormat.a \
clangTooling.a clangToolingCore.a clangFrontend.a \
USEDLIBS = modernizeCore.a clangFormat.a clangTooling.a clangFrontend.a \
clangSerialization.a clangDriver.a clangRewriteFrontend.a \
clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \
clangRewriteCore.a clangParse.a clangSema.a clangAnalysis.a \
clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@@ -1,13 +1,8 @@
set(LLVM_LINK_COMPONENTS
lineeditor
support
)
add_clang_library(clangQuery
Query.cpp
QueryParser.cpp
LINK_LIBS
)
target_link_libraries(clangQuery
clangAST
clangASTMatchers
clangBasic

View File

@@ -11,6 +11,4 @@ CLANG_LEVEL := ../../..
LIBRARYNAME := clangQuery
include $(CLANG_LEVEL)/../../Makefile.config
DIRS = tool
include $(CLANG_LEVEL)/Makefile

View File

@@ -54,12 +54,15 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
}
};
} // namespace
}
bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
unsigned MatchCount = 0;
for (auto &AST : QS.ASTs) {
for (llvm::ArrayRef<ASTUnit *>::iterator I = QS.ASTs.begin(),
E = QS.ASTs.end();
I != E; ++I) {
ASTUnit *AST = *I;
MatchFinder Finder;
std::vector<BoundNodes> Matches;
DynTypedMatcher MaybeBoundMatcher = Matcher;
@@ -92,8 +95,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
TD.emitDiagnostic(
R.getBegin(), DiagnosticsEngine::Note,
"\"" + BI->first + "\" binds here",
CharSourceRange::getTokenRange(R),
None, &AST->getSourceManager());
ArrayRef<CharSourceRange>(CharSourceRange::getTokenRange(R)),
ArrayRef<FixItHint>(), &AST->getSourceManager());
}
break;
}
@@ -121,15 +124,6 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
return true;
}
bool LetQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
if (Value) {
QS.NamedValues[Name] = Value;
} else {
QS.NamedValues.erase(Name);
}
return true;
}
#ifndef _MSC_VER
const QueryKind SetQueryKind<bool>::value;
const QueryKind SetQueryKind<OutputKind>::value;

View File

@@ -10,10 +10,10 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
#include <string>
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
#include <string>
namespace clang {
namespace query {
@@ -28,10 +28,9 @@ enum QueryKind {
QK_Invalid,
QK_NoOp,
QK_Help,
QK_Let,
QK_Match,
QK_SetBool,
QK_SetOutputKind,
QK_SetOutputKind
};
class QuerySession;
@@ -53,7 +52,7 @@ typedef llvm::IntrusiveRefCntPtr<Query> QueryRef;
/// Any query which resulted in a parse error. The error message is in ErrStr.
struct InvalidQuery : Query {
InvalidQuery(const Twine &ErrStr) : Query(QK_Invalid), ErrStr(ErrStr.str()) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
std::string ErrStr;
@@ -63,7 +62,7 @@ struct InvalidQuery : Query {
/// No-op query (i.e. a blank line).
struct NoOpQuery : Query {
NoOpQuery() : Query(QK_NoOp) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
static bool classof(const Query *Q) { return Q->Kind == QK_NoOp; }
};
@@ -71,7 +70,7 @@ struct NoOpQuery : Query {
/// Query for "help".
struct HelpQuery : Query {
HelpQuery() : Query(QK_Help) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
static bool classof(const Query *Q) { return Q->Kind == QK_Help; }
};
@@ -80,24 +79,13 @@ struct HelpQuery : Query {
struct MatchQuery : Query {
MatchQuery(const ast_matchers::dynamic::DynTypedMatcher &Matcher)
: Query(QK_Match), Matcher(Matcher) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
ast_matchers::dynamic::DynTypedMatcher Matcher;
static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
};
struct LetQuery : Query {
LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)
: Query(QK_Let), Name(Name), Value(Value) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
std::string Name;
ast_matchers::dynamic::VariantValue Value;
static bool classof(const Query *Q) { return Q->Kind == QK_Let; }
};
template <typename T> struct SetQueryKind {};
template <> struct SetQueryKind<bool> {
@@ -112,7 +100,7 @@ template <> struct SetQueryKind<OutputKind> {
template <typename T> struct SetQuery : Query {
SetQuery(T QuerySession::*Var, T Value)
: Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE {
QS.*Var = Value;
return true;
}

View File

@@ -10,11 +10,10 @@
#include "QueryParser.h"
#include "Query.h"
#include "QuerySession.h"
#include "clang/ASTMatchers/Dynamic/Parser.h"
#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include <set>
#include "clang/ASTMatchers/Dynamic/Parser.h"
#include "clang/Basic/CharInfo.h"
using namespace llvm;
using namespace clang::ast_matchers::dynamic;
@@ -26,10 +25,10 @@ namespace query {
// non-whitespace characters) from the start of region [Begin,End). If no word
// is found before End, return StringRef(). Begin is adjusted to exclude the
// lexed region.
StringRef QueryParser::lexWord() {
static StringRef LexWord(const char *&Begin, const char *End) {
while (true) {
if (Begin == End)
return StringRef(Begin, 0);
return StringRef();
if (!isWhitespace(*Begin))
break;
@@ -47,60 +46,8 @@ StringRef QueryParser::lexWord() {
}
}
// This is the StringSwitch-alike used by lexOrCompleteWord below. See that
// function for details.
template <typename T> struct QueryParser::LexOrCompleteWord {
StringSwitch<T> Switch;
QueryParser *P;
StringRef Word;
// Set to the completion point offset in Word, or StringRef::npos if
// completion point not in Word.
size_t WordCompletionPos;
LexOrCompleteWord(QueryParser *P, StringRef Word, size_t WCP)
: Switch(Word), P(P), Word(Word), WordCompletionPos(WCP) {}
template <unsigned N>
LexOrCompleteWord &Case(const char (&S)[N], const T &Value,
bool IsCompletion = true) {
StringRef CaseStr(S, N - 1);
if (WordCompletionPos == StringRef::npos)
Switch.Case(S, Value);
else if (N != 1 && IsCompletion && WordCompletionPos <= CaseStr.size() &&
CaseStr.substr(0, WordCompletionPos) ==
Word.substr(0, WordCompletionPos))
P->Completions.push_back(LineEditor::Completion(
(CaseStr.substr(WordCompletionPos) + " ").str(), CaseStr));
return *this;
}
T Default(const T& Value) const {
return Switch.Default(Value);
}
};
// Lexes a word and stores it in Word. Returns a LexOrCompleteWord<T> object
// that can be used like a llvm::StringSwitch<T>, but adds cases as possible
// completions if the lexed word contains the completion point.
template <typename T>
QueryParser::LexOrCompleteWord<T>
QueryParser::lexOrCompleteWord(StringRef &Word) {
Word = lexWord();
size_t WordCompletionPos = StringRef::npos;
if (CompletionPos && CompletionPos <= Word.data() + Word.size()) {
if (CompletionPos < Word.data())
WordCompletionPos = 0;
else
WordCompletionPos = CompletionPos - Word.data();
}
return LexOrCompleteWord<T>(this, Word, WordCompletionPos);
}
QueryRef QueryParser::parseSetBool(bool QuerySession::*Var) {
StringRef ValStr;
unsigned Value = lexOrCompleteWord<unsigned>(ValStr)
static QueryRef ParseSetBool(bool QuerySession::*Var, StringRef ValStr) {
unsigned Value = StringSwitch<unsigned>(ValStr)
.Case("false", 0)
.Case("true", 1)
.Default(~0u);
@@ -110,9 +57,8 @@ QueryRef QueryParser::parseSetBool(bool QuerySession::*Var) {
return new SetQuery<bool>(Var, Value);
}
QueryRef QueryParser::parseSetOutputKind() {
StringRef ValStr;
unsigned OutKind = lexOrCompleteWord<unsigned>(ValStr)
static QueryRef ParseSetOutputKind(StringRef ValStr) {
unsigned OutKind = StringSwitch<unsigned>(ValStr)
.Case("diag", OK_Diag)
.Case("print", OK_Print)
.Case("dump", OK_Dump)
@@ -124,24 +70,20 @@ QueryRef QueryParser::parseSetOutputKind() {
return new SetQuery<OutputKind>(&QuerySession::OutKind, OutputKind(OutKind));
}
QueryRef QueryParser::endQuery(QueryRef Q) {
static QueryRef EndQuery(const char *Begin, const char *End, QueryRef Q) {
const char *Extra = Begin;
if (!lexWord().empty())
if (!LexWord(Begin, End).empty())
return new InvalidQuery("unexpected extra input: '" +
StringRef(Extra, End - Extra) + "'");
return Q;
}
namespace {
enum ParsedQueryKind {
PQK_Invalid,
PQK_NoOp,
PQK_Help,
PQK_Let,
PQK_Match,
PQK_Set,
PQK_Unlet,
PQK_Set
};
enum ParsedQueryVariable {
@@ -150,37 +92,17 @@ enum ParsedQueryVariable {
PQV_BindRoot
};
QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) {
std::string ErrStr;
llvm::raw_string_ostream OS(ErrStr);
Diag.printToStreamFull(OS);
return new InvalidQuery(OS.str());
}
QueryRef ParseQuery(StringRef Line) {
const char *Begin = Line.data();
const char *End = Line.data() + Line.size();
} // namespace
QueryRef QueryParser::completeMatcherExpression() {
std::vector<MatcherCompletion> Comps = Parser::completeExpression(
StringRef(Begin, End - Begin), CompletionPos - Begin, nullptr,
&QS.NamedValues);
for (std::vector<MatcherCompletion>::iterator I = Comps.begin(),
E = Comps.end();
I != E; ++I) {
Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl));
}
return QueryRef();
}
QueryRef QueryParser::doParse() {
StringRef CommandStr;
ParsedQueryKind QKind = lexOrCompleteWord<ParsedQueryKind>(CommandStr)
StringRef CommandStr = LexWord(Begin, End);
ParsedQueryKind QKind = StringSwitch<ParsedQueryKind>(CommandStr)
.Case("", PQK_NoOp)
.Case("help", PQK_Help)
.Case("m", PQK_Match, /*IsCompletion=*/false)
.Case("let", PQK_Let)
.Case("m", PQK_Match)
.Case("match", PQK_Match)
.Case("set", PQK_Set)
.Case("unlet", PQK_Unlet)
.Default(PQK_Invalid);
switch (QKind) {
@@ -188,73 +110,50 @@ QueryRef QueryParser::doParse() {
return new NoOpQuery;
case PQK_Help:
return endQuery(new HelpQuery);
case PQK_Let: {
StringRef Name = lexWord();
if (Name.empty())
return new InvalidQuery("expected variable name");
if (CompletionPos)
return completeMatcherExpression();
Diagnostics Diag;
ast_matchers::dynamic::VariantValue Value;
if (!Parser::parseExpression(StringRef(Begin, End - Begin), nullptr,
&QS.NamedValues, &Value, &Diag)) {
return makeInvalidQueryFromDiagnostics(Diag);
}
return new LetQuery(Name, Value);
}
return EndQuery(Begin, End, new HelpQuery);
case PQK_Match: {
if (CompletionPos)
return completeMatcherExpression();
Diagnostics Diag;
Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(
StringRef(Begin, End - Begin), nullptr, &QS.NamedValues, &Diag);
Optional<DynTypedMatcher> Matcher =
Parser::parseMatcherExpression(StringRef(Begin, End - Begin), &Diag);
if (!Matcher) {
return makeInvalidQueryFromDiagnostics(Diag);
std::string ErrStr;
llvm::raw_string_ostream OS(ErrStr);
Diag.printToStreamFull(OS);
return new InvalidQuery(OS.str());
}
return new MatchQuery(*Matcher);
}
case PQK_Set: {
StringRef VarStr;
ParsedQueryVariable Var = lexOrCompleteWord<ParsedQueryVariable>(VarStr)
.Case("output", PQV_Output)
.Case("bind-root", PQV_BindRoot)
.Default(PQV_Invalid);
StringRef VarStr = LexWord(Begin, End);
if (VarStr.empty())
return new InvalidQuery("expected variable name");
ParsedQueryVariable Var = StringSwitch<ParsedQueryVariable>(VarStr)
.Case("output", PQV_Output)
.Case("bind-root", PQV_BindRoot)
.Default(PQV_Invalid);
if (Var == PQV_Invalid)
return new InvalidQuery("unknown variable: '" + VarStr + "'");
StringRef ValStr = LexWord(Begin, End);
if (ValStr.empty())
return new InvalidQuery("expected variable value");
QueryRef Q;
switch (Var) {
case PQV_Output:
Q = parseSetOutputKind();
Q = ParseSetOutputKind(ValStr);
break;
case PQV_BindRoot:
Q = parseSetBool(&QuerySession::BindRoot);
Q = ParseSetBool(&QuerySession::BindRoot, ValStr);
break;
case PQV_Invalid:
llvm_unreachable("Invalid query kind");
}
return endQuery(Q);
}
case PQK_Unlet: {
StringRef Name = lexWord();
if (Name.empty())
return new InvalidQuery("expected variable name");
return endQuery(new LetQuery(Name, VariantValue()));
return EndQuery(Begin, End, Q);
}
case PQK_Invalid:
@@ -264,18 +163,5 @@ QueryRef QueryParser::doParse() {
llvm_unreachable("Invalid query kind");
}
QueryRef QueryParser::parse(StringRef Line, const QuerySession &QS) {
return QueryParser(Line, QS).doParse();
}
std::vector<LineEditor::Completion>
QueryParser::complete(StringRef Line, size_t Pos, const QuerySession &QS) {
QueryParser P(Line, QS);
P.CompletionPos = Line.data() + Pos;
P.doParse();
return P.Completions;
}
} // namespace query
} // namespace clang

View File

@@ -11,60 +11,15 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PARSER_H
#include "Query.h"
#include "QuerySession.h"
#include "llvm/LineEditor/LineEditor.h"
#include <stddef.h>
namespace clang {
namespace query {
class QuerySession;
class QueryParser {
public:
/// Parse \a Line as a query.
///
/// \return A QueryRef representing the query, which may be an InvalidQuery.
static QueryRef parse(StringRef Line, const QuerySession &QS);
/// Compute a list of completions for \a Line assuming a cursor at
/// \param Pos characters past the start of \a Line, ordered from most
/// likely to least likely.
///
/// \return A vector of completions for \a Line.
static std::vector<llvm::LineEditor::Completion>
complete(StringRef Line, size_t Pos, const QuerySession &QS);
private:
QueryParser(StringRef Line, const QuerySession &QS)
: Begin(Line.begin()), End(Line.end()),
CompletionPos(nullptr), QS(QS) {}
StringRef lexWord();
template <typename T> struct LexOrCompleteWord;
template <typename T> LexOrCompleteWord<T> lexOrCompleteWord(StringRef &Str);
QueryRef parseSetBool(bool QuerySession::*Var);
QueryRef parseSetOutputKind();
QueryRef completeMatcherExpression();
QueryRef endQuery(QueryRef Q);
/// \brief Parse [\p Begin,\p End).
///
/// \return A reference to the parsed query object, which may be an
/// \c InvalidQuery if a parse error occurs.
QueryRef doParse();
const char *Begin;
const char *End;
const char *CompletionPos;
std::vector<llvm::LineEditor::Completion> Completions;
const QuerySession &QS;
};
/// \brief Parse \p Line.
///
/// \return A reference to the parsed query object, which may be an
/// \c InvalidQuery if a parse error occurs.
QueryRef ParseQuery(StringRef Line);
} // namespace query
} // namespace clang

View File

@@ -10,10 +10,8 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H
#include "Query.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "Query.h"
namespace clang {
@@ -24,13 +22,12 @@ namespace query {
/// Represents the state for a particular clang-query session.
class QuerySession {
public:
QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
QuerySession(llvm::ArrayRef<ASTUnit *> ASTs)
: ASTs(ASTs), OutKind(OK_Diag), BindRoot(true) {}
llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;
llvm::ArrayRef<ASTUnit *> ASTs;
OutputKind OutKind;
bool BindRoot;
llvm::StringMap<ast_matchers::dynamic::VariantValue> NamedValues;
};
} // namespace query

View File

@@ -1,11 +1,11 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
if(HAVE_LIBEDIT)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
add_clang_executable(clang-query ClangQuery.cpp)
target_link_libraries(clang-query
clangAST
clangASTMatchers
clangBasic
clangDynamicASTMatchers
clangQuery
clangTooling
)
add_clang_executable(clang-query ClangQuery.cpp)
target_link_libraries(clang-query
edit
clangFrontend
clangQuery
clangTooling
)
endif()

View File

@@ -27,18 +27,21 @@
//===----------------------------------------------------------------------===//
#include "Query.h"
#include "QueryParser.h"
#include "QuerySession.h"
#include "QueryParser.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/LineEditor/LineEditor.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include <fstream>
#include <string>
#include <histedit.h>
using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::ast_matchers::dynamic;
@@ -46,31 +49,51 @@ using namespace clang::query;
using namespace clang::tooling;
using namespace llvm;
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::OptionCategory ClangQueryCategory("clang-query options");
static cl::opt<std::string> BuildPath("b", cl::desc("Specify build path"),
cl::value_desc("<path>"));
static cl::list<std::string> Commands("c", cl::desc("Specify command to run"),
cl::value_desc("command"),
cl::cat(ClangQueryCategory));
cl::value_desc("<command>"));
static cl::list<std::string> CommandFiles("f",
cl::desc("Read commands from file"),
cl::value_desc("file"),
cl::cat(ClangQueryCategory));
cl::value_desc("<file>"));
static cl::list<std::string> SourcePaths(cl::Positional,
cl::desc("<source0> [... <sourceN>]"),
cl::OneOrMore);
static char *ReturnPrompt(EditLine *EL) {
static char Prompt[] = "clang-query> ";
return Prompt;
}
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
CommonOptionsParser OptionsParser(argc, argv, ClangQueryCategory);
cl::ParseCommandLineOptions(argc, argv);
if (!Commands.empty() && !CommandFiles.empty()) {
llvm::errs() << argv[0] << ": cannot specify both -c and -f\n";
return 1;
}
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
std::vector<std::unique_ptr<ASTUnit>> ASTs;
llvm::OwningPtr<CompilationDatabase> Compilations(
FixedCompilationDatabase::loadFromCommandLine(argc, argv));
if (!Compilations) { // Couldn't find a compilation DB from the command line
std::string ErrorMessage;
Compilations.reset(
!BuildPath.empty() ?
CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage) :
CompilationDatabase::autoDetectFromSource(SourcePaths[0], ErrorMessage)
);
// Still no compilation DB? - bail.
if (!Compilations)
llvm::report_fatal_error(ErrorMessage);
}
ClangTool Tool(*Compilations, SourcePaths);
std::vector<ASTUnit *> ASTs;
if (Tool.buildASTs(ASTs) != 0)
return 1;
@@ -80,7 +103,7 @@ int main(int argc, const char **argv) {
for (cl::list<std::string>::iterator I = Commands.begin(),
E = Commands.end();
I != E; ++I) {
QueryRef Q = QueryParser::parse(I->c_str(), QS);
QueryRef Q = ParseQuery(I->c_str());
if (!Q->run(llvm::outs(), QS))
return 1;
}
@@ -97,22 +120,39 @@ int main(int argc, const char **argv) {
std::string Line;
std::getline(Input, Line);
QueryRef Q = QueryParser::parse(Line.c_str(), QS);
QueryRef Q = ParseQuery(Line.c_str());
if (!Q->run(llvm::outs(), QS))
return 1;
}
}
} else {
LineEditor LE("clang-query");
LE.setListCompleter([&QS](StringRef Line, size_t Pos) {
return QueryParser::complete(Line, Pos, QS);
});
while (llvm::Optional<std::string> Line = LE.readLine()) {
QueryRef Q = QueryParser::parse(*Line, QS);
History *Hist = history_init();
HistEvent Event;
history(Hist, &Event, H_SETSIZE, 100);
EditLine *EL = el_init("clang-query", stdin, stdout, stderr);
el_set(EL, EL_PROMPT, ReturnPrompt);
el_set(EL, EL_EDITOR, "emacs");
el_set(EL, EL_HIST, history, Hist);
int Count;
while (const char *Line = el_gets(EL, &Count)) {
if (Count == 0)
break;
history(Hist, &Event, H_ENTER, Line);
QueryRef Q = ParseQuery(Line);
Q->run(llvm::outs(), QS);
llvm::outs().flush();
}
history_end(Hist);
el_end(EL);
llvm::outs() << "\n";
}
llvm::DeleteContainerPointers(ASTs);
return 0;
}

View File

@@ -1,39 +0,0 @@
##===- tools/extra/clang-query/tool/Makefile ---------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ../../../..
include $(CLANG_LEVEL)/../../Makefile.config
TOOLNAME = clang-query
# No plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
SOURCES = ClangQuery.cpp
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc mcparser option
USEDLIBS = clangQuery.a clangDynamicASTMatchers.a clangFormat.a clangTooling.a \
clangFrontend.a clangSerialization.a clangDriver.a clangRewriteFrontend.a \
LLVMLineEditor.a clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \
clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile
CPP.Flags += -I$(PROJ_SRC_DIR)/..
# BUILT_SOURCES gets used as a prereq for many top-level targets. However, at
# the point those targets are defined, $(ObjDir) hasn't been defined and so the
# directory to create becomes /<name>/ which is not what we want. So instead,
# this .objdir recipe is defined at at point where $(ObjDir) is defined and
# it's specialized to $(ObjDir) to ensure it only works on targets we want it
# to.
$(ObjDir)/%.objdir:
$(Verb) $(MKDIR) $(ObjDir)/$* > /dev/null
$(Verb) $(DOTDIR_TIMESTAMP_COMMAND) > $@

View File

@@ -1,16 +0,0 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangRename
USRFinder.cpp
USRFindingAction.cpp
USRLocFinder.cpp
RenamingAction.cpp
LINK_LIBS
clangAST
clangBasic
clangIndex
clangToolingCore
)
add_subdirectory(tool)

View File

@@ -1,16 +0,0 @@
##===- tools/extra/clang-rename/Makefile -------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ../../..
LIBRARYNAME = clangRename
include $(CLANG_LEVEL)/../../Makefile.config
DIRS = tool
include $(CLANG_LEVEL)/Makefile

View File

@@ -1,90 +0,0 @@
//===--- tools/extra/clang-rename/RenamingAction.cpp - Clang rename tool --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#include "RenamingAction.h"
#include "USRLocFinder.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace llvm;
namespace clang {
namespace rename {
class RenamingASTConsumer : public ASTConsumer {
public:
RenamingASTConsumer(const std::string &NewName,
const std::string &PrevName,
const std::vector<std::string> &USRs,
tooling::Replacements &Replaces,
bool PrintLocations)
: NewName(NewName), PrevName(PrevName), USRs(USRs), Replaces(Replaces),
PrintLocations(PrintLocations) {
}
void HandleTranslationUnit(ASTContext &Context) override {
const auto &SourceMgr = Context.getSourceManager();
std::vector<SourceLocation> RenamingCandidates;
std::vector<SourceLocation> NewCandidates;
for (const auto &USR : USRs) {
NewCandidates = getLocationsOfUSR(USR, Context.getTranslationUnitDecl());
RenamingCandidates.insert(RenamingCandidates.end(), NewCandidates.begin(),
NewCandidates.end());
NewCandidates.clear();
}
auto PrevNameLen = PrevName.length();
if (PrintLocations)
for (const auto &Loc : RenamingCandidates) {
FullSourceLoc FullLoc(Loc, SourceMgr);
errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)
<< ":" << FullLoc.getSpellingLineNumber() << ":"
<< FullLoc.getSpellingColumnNumber() << "\n";
Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
NewName));
}
else
for (const auto &Loc : RenamingCandidates)
Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
NewName));
}
private:
const std::string &NewName, &PrevName;
const std::vector<std::string> &USRs;
tooling::Replacements &Replaces;
bool PrintLocations;
};
std::unique_ptr<ASTConsumer> RenamingAction::newASTConsumer() {
return llvm::make_unique<RenamingASTConsumer>(NewName, PrevName, USRs,
Replaces, PrintLocations);
}
}
}

View File

@@ -1,47 +0,0 @@
//===--- tools/extra/clang-rename/RenamingAction.h - Clang rename tool ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
#include "clang/Tooling/Refactoring.h"
namespace clang {
class ASTConsumer;
class CompilerInstance;
namespace rename {
class RenamingAction {
public:
RenamingAction(const std::string &NewName, const std::string &PrevName,
const std::vector<std::string> &USRs,
tooling::Replacements &Replaces, bool PrintLocations = false)
: NewName(NewName), PrevName(PrevName), USRs(USRs), Replaces(Replaces),
PrintLocations(PrintLocations) {
}
std::unique_ptr<ASTConsumer> newASTConsumer();
private:
const std::string &NewName, &PrevName;
const std::vector<std::string> &USRs;
tooling::Replacements &Replaces;
bool PrintLocations;
};
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_

View File

@@ -1,162 +0,0 @@
//===--- tools/extra/clang-rename/USRFinder.cpp - Clang rename tool -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file Implements a recursive AST visitor that finds the USR of a symbol at a
/// point.
///
//===----------------------------------------------------------------------===//
#include "USRFinder.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
namespace clang {
namespace rename {
// NamedDeclFindingASTVisitor recursively visits each AST node to find the
// symbol underneath the cursor.
// FIXME: move to seperate .h/.cc file if this gets too large.
namespace {
class NamedDeclFindingASTVisitor
: public clang::RecursiveASTVisitor<NamedDeclFindingASTVisitor> {
public:
// \brief Finds the NamedDecl at a point in the source.
// \param Point the location in the source to search for the NamedDecl.
explicit NamedDeclFindingASTVisitor(const SourceManager &SourceMgr,
const SourceLocation Point)
: Result(nullptr), SourceMgr(SourceMgr),
Point(Point) {
}
// Declaration visitors:
// \brief Checks if the point falls within the NameDecl. This covers every
// declaration of a named entity that we may come across. Usually, just
// checking if the point lies within the length of the name of the declaration
// and the start location is sufficient.
bool VisitNamedDecl(const NamedDecl *Decl) {
return setResult(Decl, Decl->getLocation(),
Decl->getNameAsString().length());
}
// Expression visitors:
bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
// Check the namespace specifier first.
if (!checkNestedNameSpecifierLoc(Expr->getQualifierLoc()))
return false;
const auto *Decl = Expr->getFoundDecl();
return setResult(Decl, Expr->getLocation(),
Decl->getNameAsString().length());
}
bool VisitMemberExpr(const MemberExpr *Expr) {
const auto *Decl = Expr->getFoundDecl().getDecl();
return setResult(Decl, Expr->getMemberLoc(),
Decl->getNameAsString().length());
}
// Other:
const NamedDecl *getNamedDecl() {
return Result;
}
private:
// \brief Determines if a namespace qualifier contains the point.
// \returns false on success and sets Result.
bool checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
while (NameLoc) {
const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
if (Decl && !setResult(Decl, NameLoc.getLocalBeginLoc(),
Decl->getNameAsString().length()))
return false;
NameLoc = NameLoc.getPrefix();
}
return true;
}
// \brief Sets Result to Decl if the Point is within Start and End.
// \returns false on success.
bool setResult(const NamedDecl *Decl, SourceLocation Start,
SourceLocation End) {
if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
!End.isFileID() || !isPointWithin(Start, End)) {
return true;
}
Result = Decl;
return false;
}
// \brief Sets Result to Decl if Point is within Loc and Loc + Offset.
// \returns false on success.
bool setResult(const NamedDecl *Decl, SourceLocation Loc,
unsigned Offset) {
// FIXME: Add test for Offset == 0. Add test for Offset - 1 (vs -2 etc).
return Offset == 0 ||
setResult(Decl, Loc, Loc.getLocWithOffset(Offset - 1));
}
// \brief Determines if the Point is within Start and End.
bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
// FIXME: Add tests for Point == End.
return Point == Start || Point == End ||
(SourceMgr.isBeforeInTranslationUnit(Start, Point) &&
SourceMgr.isBeforeInTranslationUnit(Point, End));
}
const NamedDecl *Result;
const SourceManager &SourceMgr;
const SourceLocation Point; // The location to find the NamedDecl.
};
}
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point) {
const auto &SourceMgr = Context.getSourceManager();
const auto SearchFile = SourceMgr.getFilename(Point);
NamedDeclFindingASTVisitor Visitor(SourceMgr, Point);
// We only want to search the decls that exist in the same file as the point.
auto Decls = Context.getTranslationUnitDecl()->decls();
for (auto &CurrDecl : Decls) {
const auto FileLoc = CurrDecl->getLocStart();
const auto FileName = SourceMgr.getFilename(FileLoc);
// FIXME: Add test.
if (FileName == SearchFile) {
Visitor.TraverseDecl(CurrDecl);
if (const NamedDecl *Result = Visitor.getNamedDecl()) {
return Result;
}
}
}
return nullptr;
}
std::string getUSRForDecl(const Decl *Decl) {
llvm::SmallVector<char, 128> Buff;
// FIXME: Add test for the nullptr case.
if (Decl == nullptr || index::generateUSRForDecl(Decl, Buff))
return "";
return std::string(Buff.data(), Buff.size());
}
} // namespace clang
} // namespace rename

View File

@@ -1,39 +0,0 @@
//===--- tools/extra/clang-rename/USRFinder.h - Clang rename tool ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Methods for determining the USR of a symbol at a location in source
/// code.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
#include <string>
namespace clang {
class ASTContext;
class Decl;
class SourceLocation;
class NamedDecl;
namespace rename {
// Given an AST context and a point, returns a NamedDecl identifying the symbol
// at the point. Returns null if nothing is found at the point.
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point);
// Converts a Decl into a USR.
std::string getUSRForDecl(const Decl *Decl);
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H

View File

@@ -1,118 +0,0 @@
//===--- tools/extra/clang-rename/USRFindingAction.cpp - Clang rename tool ===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#include "USRFindingAction.h"
#include "USRFinder.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace llvm;
namespace clang {
namespace rename {
// Get the USRs for the constructors of the class.
static std::vector<std::string> getAllConstructorUSRs(
const CXXRecordDecl *Decl) {
std::vector<std::string> USRs;
// We need to get the definition of the record (as opposed to any forward
// declarations) in order to find the constructor and destructor.
const auto *RecordDecl = Decl->getDefinition();
// Iterate over all the constructors and add their USRs.
for (const auto &CtorDecl : RecordDecl->ctors())
USRs.push_back(getUSRForDecl(CtorDecl));
// Ignore destructors. GetLocationsOfUSR will find the declaration of and
// explicit calls to a destructor through TagTypeLoc (and it is better for the
// purpose of renaming).
//
// For example, in the following code segment,
// 1 class C {
// 2 ~C();
// 3 };
// At line 3, there is a NamedDecl starting from '~' and a TagTypeLoc starting
// from 'C'.
return USRs;
}
struct NamedDeclFindingConsumer : public ASTConsumer {
void HandleTranslationUnit(ASTContext &Context) override {
const auto &SourceMgr = Context.getSourceManager();
// The file we look for the USR in will always be the main source file.
const auto Point = SourceMgr.getLocForStartOfFile(
SourceMgr.getMainFileID()).getLocWithOffset(SymbolOffset);
if (!Point.isValid())
return;
const NamedDecl *FoundDecl = getNamedDeclAt(Context, Point);
if (FoundDecl == nullptr) {
FullSourceLoc FullLoc(Point, SourceMgr);
errs() << "clang-rename: could not find symbol at "
<< SourceMgr.getFilename(Point) << ":"
<< FullLoc.getSpellingLineNumber() << ":"
<< FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset
<< ").\n";
return;
}
// If the decl is a constructor or destructor, we want to instead take the
// decl of the parent record.
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
FoundDecl = CtorDecl->getParent();
else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
FoundDecl = DtorDecl->getParent();
// If the decl is in any way relatedpp to a class, we want to make sure we
// search for the constructor and destructor as well as everything else.
if (const auto *Record = dyn_cast<CXXRecordDecl>(FoundDecl))
*USRs = getAllConstructorUSRs(Record);
USRs->push_back(getUSRForDecl(FoundDecl));
*SpellingName = FoundDecl->getNameAsString();
}
unsigned SymbolOffset;
std::string *SpellingName;
std::vector<std::string> *USRs;
};
std::unique_ptr<ASTConsumer>
USRFindingAction::newASTConsumer() {
std::unique_ptr<NamedDeclFindingConsumer> Consumer(
new NamedDeclFindingConsumer);
SpellingName = "";
Consumer->SymbolOffset = SymbolOffset;
Consumer->USRs = &USRs;
Consumer->SpellingName = &SpellingName;
return std::move(Consumer);
}
} // namespace rename
} // namespace clang

View File

@@ -1,50 +0,0 @@
//===--- tools/extra/clang-rename/USRFindingAction.h - Clang rename tool --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to find all relevent USRs at a point.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
#include "clang/Frontend/FrontendAction.h"
namespace clang {
class ASTConsumer;
class CompilerInstance;
class NamedDecl;
namespace rename {
struct USRFindingAction {
USRFindingAction(unsigned Offset) : SymbolOffset(Offset) {
}
std::unique_ptr<ASTConsumer> newASTConsumer();
// \brief get the spelling of the USR(s) as it would appear in source files.
const std::string &getUSRSpelling() {
return SpellingName;
}
const std::vector<std::string> &getUSRs() {
return USRs;
}
private:
unsigned SymbolOffset;
std::string SpellingName;
std::vector<std::string> USRs;
};
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_

View File

@@ -1,103 +0,0 @@
//===--- tools/extra/clang-rename/USRLocFinder.cpp - Clang rename tool ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Mehtods for finding all instances of a USR. Our strategy is very
/// simple; we just compare the USR at every relevant AST node with the one
/// provided.
///
//===----------------------------------------------------------------------===//
#include "USRLocFinder.h"
#include "USRFinder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
namespace clang {
namespace rename {
namespace {
// \brief This visitor recursively searches for all instances of a USR in a
// translation unit and stores them for later usage.
class USRLocFindingASTVisitor
: public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
public:
explicit USRLocFindingASTVisitor(const std::string USR) : USR(USR) {
}
// Declaration visitors:
bool VisitNamedDecl(const NamedDecl *Decl) {
if (getUSRForDecl(Decl) == USR) {
LocationsFound.push_back(Decl->getLocation());
}
return true;
}
// Expression visitors:
bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
const auto *Decl = Expr->getFoundDecl();
checkNestedNameSpecifierLoc(Expr->getQualifierLoc());
if (getUSRForDecl(Decl) == USR) {
LocationsFound.push_back(Expr->getLocation());
}
return true;
}
bool VisitMemberExpr(const MemberExpr *Expr) {
const auto *Decl = Expr->getFoundDecl().getDecl();
if (getUSRForDecl(Decl) == USR) {
LocationsFound.push_back(Expr->getMemberLoc());
}
return true;
}
// Non-visitors:
// \brief Returns a list of unique locations. Duplicate or overlapping
// locations are erroneous and should be reported!
const std::vector<clang::SourceLocation> &getLocationsFound() const {
return LocationsFound;
}
private:
// Namespace traversal:
void checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
while (NameLoc) {
const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
if (Decl && getUSRForDecl(Decl) == USR)
LocationsFound.push_back(NameLoc.getLocalBeginLoc());
NameLoc = NameLoc.getPrefix();
}
}
// All the locations of the USR were found.
const std::string USR;
std::vector<clang::SourceLocation> LocationsFound;
};
} // namespace
std::vector<SourceLocation> getLocationsOfUSR(const std::string USR,
Decl *Decl) {
USRLocFindingASTVisitor visitor(USR);
visitor.TraverseDecl(Decl);
return visitor.getLocationsFound();
}
} // namespace rename
} // namespace clang

View File

@@ -1,35 +0,0 @@
//===--- tools/extra/clang-rename/USRLocFinder.h - Clang rename tool ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides functionality for finding all instances of a USR in a given
/// AST.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
#include <string>
#include <vector>
namespace clang {
class Decl;
class SourceLocation;
namespace rename {
// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
std::vector<SourceLocation> getLocationsOfUSR(const std::string usr,
Decl *decl);
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H

View File

@@ -1,11 +0,0 @@
add_clang_executable(clang-rename ClangRename.cpp)
target_link_libraries(clang-rename
clangBasic
clangFrontend
clangRename
clangRewrite
clangTooling
)
install(TARGETS clang-rename RUNTIME DESTINATION bin)

View File

@@ -1,151 +0,0 @@
//===--- tools/extra/clang-rename/ClangRename.cpp - Clang rename tool -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a clang-rename tool that automatically finds and
/// renames symbols in C++ code.
///
//===----------------------------------------------------------------------===//
#include "../USRFindingAction.h"
#include "../RenamingAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Parse/Parser.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/Host.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <vector>
using namespace llvm;
cl::OptionCategory ClangRenameCategory("Clang-rename options");
static cl::opt<std::string>
NewName(
"new-name",
cl::desc("The new name to change the symbol to."),
cl::cat(ClangRenameCategory));
static cl::opt<unsigned>
SymbolOffset(
"offset",
cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
cl::cat(ClangRenameCategory));
static cl::opt<bool>
Inplace(
"i",
cl::desc("Overwrite edited <file>s."),
cl::cat(ClangRenameCategory));
static cl::opt<bool>
PrintName(
"pn",
cl::desc("Print the found symbol's name prior to renaming to stderr."),
cl::cat(ClangRenameCategory));
static cl::opt<bool>
PrintLocations(
"pl",
cl::desc("Print the locations affected by renaming to stderr."),
cl::cat(ClangRenameCategory));
#define CLANG_RENAME_VERSION "0.0.1"
static void PrintVersion() {
outs() << "clang-rename version " << CLANG_RENAME_VERSION << "\n";
}
using namespace clang;
const char RenameUsage[] = "A tool to rename symbols in C/C++ code.\n\
clang-rename renames every occurrence of a symbol found at <offset> in\n\
<source0>. If -i is specified, the edited files are overwritten to disk.\n\
Otherwise, the results are written to stdout.\n";
int main(int argc, const char **argv) {
cl::SetVersionPrinter(PrintVersion);
tooling::CommonOptionsParser OP(argc, argv, ClangRenameCategory, RenameUsage);
// Check the arguments for correctness.
if (NewName.empty()) {
errs() << "clang-rename: no new name provided.\n\n";
cl::PrintHelpMessage();
exit(1);
}
// Get the USRs.
auto Files = OP.getSourcePathList();
tooling::RefactoringTool Tool(OP.getCompilations(), Files);
rename::USRFindingAction USRAction(SymbolOffset);
// Find the USRs.
Tool.run(tooling::newFrontendActionFactory(&USRAction).get());
const auto &USRs = USRAction.getUSRs();
const auto &PrevName = USRAction.getUSRSpelling();
if (PrevName.empty())
// An error should have already been printed.
exit(1);
if (PrintName)
errs() << "clang-rename: found name: " << PrevName;
// Perform the renaming.
rename::RenamingAction RenameAction(NewName, PrevName, USRs,
Tool.getReplacements(), PrintLocations);
auto Factory = tooling::newFrontendActionFactory(&RenameAction);
int res;
if (Inplace) {
res = Tool.runAndSave(Factory.get());
} else {
res = Tool.run(Factory.get());
// Write every file to stdout. Right now we just barf the files without any
// indication of which files start where, other than that we print the files
// in the same order we see them.
LangOptions DefaultLangOptions;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
new DiagnosticOptions();
TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
&*DiagOpts, &DiagnosticPrinter, false);
auto &FileMgr = Tool.getFiles();
SourceManager Sources(Diagnostics, FileMgr);
Rewriter Rewrite(Sources, DefaultLangOptions);
Tool.applyAllReplacements(Rewrite);
for (const auto &File : Files) {
const auto *Entry = FileMgr.getFile(File);
auto ID = Sources.translateFile(Entry);
Rewrite.getEditBuffer(ID).write(outs());
}
}
exit(res);
}

View File

@@ -1,13 +0,0 @@
CLANG_LEVEL := ../../../..
TOOLNAME = clang-rename
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangRename.a clangFrontend.a clangSerialization.a clangDriver.a \
clangTooling.a clangToolingCore.a \
clangParse.a clangSema.a clangIndex.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a clangAnalysis.a clangRewriteFrontend.a \
clangRewrite.a clangEdit.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@@ -1,32 +1,23 @@
set(LLVM_LINK_COMPONENTS
Support
${LLVM_TARGETS_TO_BUILD}
asmparser
bitreader
support
mc
)
add_clang_library(clangTidy
ClangTidy.cpp
ClangTidyModule.cpp
ClangTidyDiagnosticConsumer.cpp
ClangTidyOptions.cpp
DEPENDS
ClangSACheckers
LINK_LIBS
clangAST
clangASTMatchers
clangBasic
clangFrontend
clangRewrite
clangSema
clangStaticAnalyzerCore
clangStaticAnalyzerFrontend
)
target_link_libraries(clangTidy
clangTooling
clangToolingCore
clangBasic
clangRewriteFrontend
clangStaticAnalyzerFrontend
clangStaticAnalyzerCheckers
)
add_subdirectory(tool)
add_subdirectory(llvm)
add_subdirectory(google)
add_subdirectory(misc)
add_subdirectory(readability)
add_subdirectory(utils)

View File

@@ -22,297 +22,194 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/ReplacementsYaml.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include <algorithm>
#include <utility>
#include <vector>
using namespace clang::ast_matchers;
using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;
template class llvm::Registry<clang::tidy::ClangTidyModule>;
namespace clang {
namespace tidy {
namespace {
static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
static StringRef StaticAnalyzerChecks[] = {
/// \brief A combined ASTConsumer that forwards calls to two different
/// consumers.
///
/// FIXME: This currently forwards just enough methods for the static analyzer
/// and the \c MatchFinder's consumer to work; expand this to all methods of
/// ASTConsumer and put it into a common location.
class CombiningASTConsumer : public ASTConsumer {
public:
CombiningASTConsumer(ASTConsumer *Consumer1, ASTConsumer *Consumer2)
: Consumer1(Consumer1), Consumer2(Consumer2) {}
virtual void Initialize(ASTContext &Context) LLVM_OVERRIDE {
Consumer1->Initialize(Context);
Consumer2->Initialize(Context);
}
virtual bool HandleTopLevelDecl(DeclGroupRef D) LLVM_OVERRIDE {
return Consumer1->HandleTopLevelDecl(D) && Consumer2->HandleTopLevelDecl(D);
}
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) LLVM_OVERRIDE {
Consumer1->HandleTopLevelDeclInObjCContainer(D);
Consumer2->HandleTopLevelDeclInObjCContainer(D);
}
virtual void HandleTranslationUnit(ASTContext &Context) LLVM_OVERRIDE {
Consumer1->HandleTranslationUnit(Context);
Consumer2->HandleTranslationUnit(Context);
}
private:
llvm::OwningPtr<ASTConsumer> Consumer1;
llvm::OwningPtr<ASTConsumer> Consumer2;
};
/// \brief Action that runs clang-tidy and static analyzer checks.
///
/// FIXME: Note that this inherits from \c AnalysisAction as this is the only
/// way we can currently get to AnalysisAction::CreateASTConsumer. Ideally
/// we'd want to build a more generic way to use \c FrontendAction based
/// checkers in clang-tidy, but that needs some preparation work first.
class ClangTidyAction : public ento::AnalysisAction {
public:
ClangTidyAction(StringRef CheckRegexString,
SmallVectorImpl<ClangTidyCheck *> &Checks,
ClangTidyContext &Context, MatchFinder &Finder)
: CheckRegexString(CheckRegexString), Checks(Checks), Context(Context),
Finder(Finder) {}
private:
clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &Compiler,
StringRef File) LLVM_OVERRIDE {
AnalyzerOptionsRef Options = Compiler.getAnalyzerOpts();
llvm::Regex CheckRegex(CheckRegexString);
// Always add all core checkers if any other static analyzer checks are
// enabled. This is currently necessary, as other path sensitive checks rely
// on the core checkers.
if (CheckRegex.match("clang-analyzer-"))
Options->CheckersControlList.push_back(std::make_pair("core", true));
// Run our regex against all possible static analyzer checkers.
// Note that debug checkers print values / run programs to visualize the CFG
// and are thus not applicable to clang-tidy in general.
#define GET_CHECKERS
#define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN) \
FULLNAME,
if (!StringRef(FULLNAME).startswith("core") && \
!StringRef(FULLNAME).startswith("debug") && \
CheckRegex.match("clang-analyzer-" FULLNAME)) \
Options->CheckersControlList.push_back(std::make_pair(FULLNAME, true));
#include "../../../lib/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
#undef GET_CHECKERS
};
class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
public:
AnalyzerDiagnosticConsumer(ClangTidyContext &Context) : Context(Context) {}
void FlushDiagnosticsImpl(std::vector<const ento::PathDiagnostic *> &Diags,
FilesMade *filesMade) override {
for (const ento::PathDiagnostic *PD : Diags) {
SmallString<64> CheckName(AnalyzerCheckNamePrefix);
CheckName += PD->getCheckName();
Context.diag(CheckName, PD->getLocation().asLocation(),
PD->getShortDescription())
<< PD->path.back()->getRanges();
for (const auto &DiagPiece :
PD->path.flatten(/*ShouldFlattenMacros=*/true)) {
Context.diag(CheckName, DiagPiece->getLocation().asLocation(),
DiagPiece->getString(), DiagnosticIDs::Note)
<< DiagPiece->getRanges();
}
}
Options->AnalysisStoreOpt = RegionStoreModel;
Options->AnalysisDiagOpt = PD_TEXT;
Options->AnalyzeNestedBlocks = true;
Options->eagerlyAssumeBinOpBifurcation = true;
return new CombiningASTConsumer(
Finder.newASTConsumer(),
ento::AnalysisAction::CreateASTConsumer(Compiler, File));
}
StringRef getName() const override { return "ClangTidyDiags"; }
bool supportsLogicalOpControlFlow() const override { return true; }
bool supportsCrossFileDiagnostics() const override { return true; }
virtual bool BeginSourceFileAction(CompilerInstance &Compiler,
llvm::StringRef Filename) LLVM_OVERRIDE {
if (!ento::AnalysisAction::BeginSourceFileAction(Compiler, Filename))
return false;
Context.setSourceManager(&Compiler.getSourceManager());
for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
E = Checks.end();
I != E; ++I)
(*I)->registerPPCallbacks(Compiler);
return true;
}
private:
std::string CheckRegexString;
SmallVectorImpl<ClangTidyCheck *> &Checks;
ClangTidyContext &Context;
MatchFinder &Finder;
};
class ErrorReporter {
class ClangTidyActionFactory : public FrontendActionFactory {
public:
ErrorReporter(bool ApplyFixes)
: Files(FileSystemOptions()), DiagOpts(new DiagnosticOptions()),
DiagPrinter(new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts)),
Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts,
DiagPrinter),
SourceMgr(Diags, Files), Rewrite(SourceMgr, LangOpts),
ApplyFixes(ApplyFixes), TotalFixes(0), AppliedFixes(0) {
DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors();
DiagPrinter->BeginSourceFile(LangOpts);
ClangTidyActionFactory(StringRef CheckRegexString, ClangTidyContext &Context)
: CheckRegexString(CheckRegexString), Context(Context) {
ClangTidyCheckFactories CheckFactories;
for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
E = ClangTidyModuleRegistry::end();
I != E; ++I) {
OwningPtr<ClangTidyModule> Module(I->instantiate());
Module->addCheckFactories(CheckFactories);
}
SmallVector<ClangTidyCheck *, 16> Checks;
CheckFactories.createChecks(CheckRegexString, Checks);
for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
E = Checks.end();
I != E; ++I) {
(*I)->setContext(&Context);
(*I)->registerMatchers(&Finder);
}
}
void reportDiagnostic(const ClangTidyError &Error) {
const ClangTidyMessage &Message = Error.Message;
SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
// Contains a pair for each attempted fix: location and whether the fix was
// applied successfully.
SmallVector<std::pair<SourceLocation, bool>, 4> FixLocations;
{
auto Level = static_cast<DiagnosticsEngine::Level>(Error.DiagLevel);
DiagnosticBuilder Diag =
Diags.Report(Loc, Diags.getCustomDiagID(Level, "%0 [%1]"))
<< Message.Message << Error.CheckName;
for (const tooling::Replacement &Fix : Error.Fix) {
SourceLocation FixLoc = getLocation(Fix.getFilePath(), Fix.getOffset());
SourceLocation FixEndLoc = FixLoc.getLocWithOffset(Fix.getLength());
Diag << FixItHint::CreateReplacement(SourceRange(FixLoc, FixEndLoc),
Fix.getReplacementText());
++TotalFixes;
if (ApplyFixes) {
bool Success = Fix.isApplicable() && Fix.apply(Rewrite);
if (Success)
++AppliedFixes;
FixLocations.push_back(std::make_pair(FixLoc, Success));
}
}
}
for (auto Fix : FixLocations) {
Diags.Report(Fix.first, Fix.second ? diag::note_fixit_applied
: diag::note_fixit_failed);
}
for (const ClangTidyMessage &Note : Error.Notes)
reportNote(Note);
}
void Finish() {
// FIXME: Run clang-format on changes.
if (ApplyFixes && TotalFixes > 0) {
llvm::errs() << "clang-tidy applied " << AppliedFixes << " of "
<< TotalFixes << " suggested fixes.\n";
Rewrite.overwriteChangedFiles();
}
virtual FrontendAction *create() {
return new ClangTidyAction(CheckRegexString, Checks, Context, Finder);
}
private:
SourceLocation getLocation(StringRef FilePath, unsigned Offset) {
if (FilePath.empty())
return SourceLocation();
const FileEntry *File = SourceMgr.getFileManager().getFile(FilePath);
FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
return SourceMgr.getLocForStartOfFile(ID).getLocWithOffset(Offset);
}
void reportNote(const ClangTidyMessage &Message) {
SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
DiagnosticBuilder Diag =
Diags.Report(Loc, Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0"))
<< Message.Message;
}
FileManager Files;
LangOptions LangOpts; // FIXME: use langopts from each original file
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
DiagnosticConsumer *DiagPrinter;
DiagnosticsEngine Diags;
SourceManager SourceMgr;
Rewriter Rewrite;
bool ApplyFixes;
unsigned TotalFixes;
unsigned AppliedFixes;
};
class ClangTidyASTConsumer : public MultiplexConsumer {
public:
ClangTidyASTConsumer(std::vector<std::unique_ptr<ASTConsumer>> Consumers,
std::unique_ptr<ast_matchers::MatchFinder> Finder,
std::vector<std::unique_ptr<ClangTidyCheck>> Checks)
: MultiplexConsumer(std::move(Consumers)), Finder(std::move(Finder)),
Checks(std::move(Checks)) {}
private:
std::unique_ptr<ast_matchers::MatchFinder> Finder;
std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
std::string CheckRegexString;
SmallVector<ClangTidyCheck *, 8> Checks;
ClangTidyContext &Context;
MatchFinder Finder;
};
} // namespace
ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
ClangTidyContext &Context)
: Context(Context), CheckFactories(new ClangTidyCheckFactories) {
for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
E = ClangTidyModuleRegistry::end();
I != E; ++I) {
std::unique_ptr<ClangTidyModule> Module(I->instantiate());
Module->addCheckFactories(*CheckFactories);
}
ClangTidyMessage::ClangTidyMessage(StringRef Message) : Message(Message) {}
ClangTidyMessage::ClangTidyMessage(StringRef Message,
const SourceManager &Sources,
SourceLocation Loc)
: Message(Message) {
FilePath = Sources.getFilename(Loc);
FileOffset = Sources.getFileOffset(Loc);
}
std::unique_ptr<clang::ASTConsumer>
ClangTidyASTConsumerFactory::CreateASTConsumer(
clang::CompilerInstance &Compiler, StringRef File) {
// FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
// modify Compiler.
Context.setSourceManager(&Compiler.getSourceManager());
Context.setCurrentFile(File);
Context.setASTContext(&Compiler.getASTContext());
ClangTidyError::ClangTidyError(const ClangTidyMessage &Message)
: Message(Message) {}
std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
CheckFactories->createChecks(&Context, Checks);
ast_matchers::MatchFinder::MatchFinderOptions FinderOptions;
if (auto *P = Context.getCheckProfileData())
FinderOptions.CheckProfiling.emplace(P->Records);
std::unique_ptr<ast_matchers::MatchFinder> Finder(
new ast_matchers::MatchFinder(std::move(FinderOptions)));
for (auto &Check : Checks) {
Check->registerMatchers(&*Finder);
Check->registerPPCallbacks(Compiler);
}
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
if (!Checks.empty())
Consumers.push_back(Finder->newASTConsumer());
AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
// FIXME: Remove this option once clang's cfg-temporary-dtors option defaults
// to true.
AnalyzerOptions->Config["cfg-temporary-dtors"] =
Context.getOptions().AnalyzeTemporaryDtors ? "true" : "false";
GlobList &Filter = Context.getChecksFilter();
AnalyzerOptions->CheckersControlList = getCheckersControlList(Filter);
if (!AnalyzerOptions->CheckersControlList.empty()) {
AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
AnalyzerOptions->AnalyzeNestedBlocks = true;
AnalyzerOptions->eagerlyAssumeBinOpBifurcation = true;
std::unique_ptr<ento::AnalysisASTConsumer> AnalysisConsumer =
ento::CreateAnalysisConsumer(Compiler);
AnalysisConsumer->AddDiagnosticConsumer(
new AnalyzerDiagnosticConsumer(Context));
Consumers.push_back(std::move(AnalysisConsumer));
}
return llvm::make_unique<ClangTidyASTConsumer>(
std::move(Consumers), std::move(Finder), std::move(Checks));
DiagnosticBuilder ClangTidyContext::Diag(SourceLocation Loc,
StringRef Message) {
return DiagEngine->Report(
Loc, DiagEngine->getCustomDiagID(DiagnosticsEngine::Warning, Message));
}
std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
std::vector<std::string> CheckNames;
GlobList &Filter = Context.getChecksFilter();
for (const auto &CheckFactory : *CheckFactories) {
if (Filter.contains(CheckFactory.first))
CheckNames.push_back(CheckFactory.first);
}
for (const auto &AnalyzerCheck : getCheckersControlList(Filter))
CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first);
std::sort(CheckNames.begin(), CheckNames.end());
return CheckNames;
void ClangTidyContext::setDiagnosticsEngine(DiagnosticsEngine *Engine) {
DiagEngine = Engine;
}
ClangTidyOptions::OptionMap ClangTidyASTConsumerFactory::getCheckOptions() {
ClangTidyOptions::OptionMap Options;
std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
CheckFactories->createChecks(&Context, Checks);
for (const auto &Check : Checks)
Check->storeOptions(Options);
return Options;
void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
DiagEngine->setSourceManager(SourceMgr);
}
ClangTidyASTConsumerFactory::CheckersList
ClangTidyASTConsumerFactory::getCheckersControlList(GlobList &Filter) {
CheckersList List;
bool AnalyzerChecksEnabled = false;
for (StringRef CheckName : StaticAnalyzerChecks) {
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
AnalyzerChecksEnabled =
AnalyzerChecksEnabled ||
(!CheckName.startswith("debug") && Filter.contains(Checker));
}
if (AnalyzerChecksEnabled) {
// Run our regex against all possible static analyzer checkers. Note that
// debug checkers print values / run programs to visualize the CFG and are
// thus not applicable to clang-tidy in general.
//
// Always add all core checkers if any other static analyzer checks are
// enabled. This is currently necessary, as other path sensitive checks
// rely on the core checkers.
for (StringRef CheckName : StaticAnalyzerChecks) {
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
if (CheckName.startswith("core") ||
(!CheckName.startswith("debug") && Filter.contains(Checker)))
List.push_back(std::make_pair(CheckName, true));
}
}
return List;
}
DiagnosticBuilder ClangTidyCheck::diag(SourceLocation Loc, StringRef Message,
DiagnosticIDs::Level Level) {
return Context->diag(CheckName, Loc, Message, Level);
/// \brief Store a \c ClangTidyError.
void ClangTidyContext::storeError(const ClangTidyError &Error) {
Errors->push_back(Error);
}
void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
@@ -320,100 +217,62 @@ void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
check(Result);
}
OptionsView::OptionsView(StringRef CheckName,
const ClangTidyOptions::OptionMap &CheckOptions)
: NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
std::string OptionsView::get(StringRef LocalName, std::string Default) const {
const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
if (Iter != CheckOptions.end())
return Iter->second;
return Default;
FrontendActionFactory *createClangTidyActionFactory(StringRef CheckRegexString,
ClangTidyContext &Context) {
return new ClangTidyActionFactory(CheckRegexString, Context);
}
void OptionsView::store(ClangTidyOptions::OptionMap &Options,
StringRef LocalName, StringRef Value) const {
Options[NamePrefix + LocalName.str()] = Value;
}
void OptionsView::store(ClangTidyOptions::OptionMap &Options,
StringRef LocalName, int64_t Value) const {
store(Options, LocalName, llvm::itostr(Value));
}
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
clang::tidy::ClangTidyContext Context(
llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
Options));
ClangTidyASTConsumerFactory Factory(Context);
return Factory.getCheckNames();
}
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options) {
clang::tidy::ClangTidyContext Context(
llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
Options));
ClangTidyASTConsumerFactory Factory(Context);
return Factory.getCheckOptions();
}
ClangTidyStats
runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> InputFiles,
std::vector<ClangTidyError> *Errors, ProfileData *Profile) {
ClangTool Tool(Compilations, InputFiles);
clang::tidy::ClangTidyContext Context(std::move(OptionsProvider));
if (Profile)
Context.setCheckProfileData(Profile);
void runClangTidy(StringRef CheckRegexString,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> Ranges,
SmallVectorImpl<ClangTidyError> *Errors) {
// FIXME: Ranges are currently full files. Support selecting specific
// (line-)ranges.
ClangTool Tool(Compilations, Ranges);
clang::tidy::ClangTidyContext Context(Errors);
ClangTidyDiagnosticConsumer DiagConsumer(Context);
Tool.setDiagnosticConsumer(&DiagConsumer);
class ActionFactory : public FrontendActionFactory {
public:
ActionFactory(ClangTidyContext &Context) : ConsumerFactory(Context) {}
FrontendAction *create() override { return new Action(&ConsumerFactory); }
private:
class Action : public ASTFrontendAction {
public:
Action(ClangTidyASTConsumerFactory *Factory) : Factory(Factory) {}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
StringRef File) override {
return Factory->CreateASTConsumer(Compiler, File);
}
private:
ClangTidyASTConsumerFactory *Factory;
};
ClangTidyASTConsumerFactory ConsumerFactory;
};
ActionFactory Factory(Context);
Tool.run(&Factory);
*Errors = Context.getErrors();
return Context.getStats();
Tool.run(createClangTidyActionFactory(CheckRegexString, Context));
}
void handleErrors(const std::vector<ClangTidyError> &Errors, bool Fix) {
ErrorReporter Reporter(Fix);
for (const ClangTidyError &Error : Errors)
Reporter.reportDiagnostic(Error);
Reporter.Finish();
static void reportDiagnostic(const ClangTidyMessage &Message,
SourceManager &SourceMgr,
DiagnosticsEngine::Level Level,
DiagnosticsEngine &Diags) {
SourceLocation Loc;
if (!Message.FilePath.empty()) {
const FileEntry *File =
SourceMgr.getFileManager().getFile(Message.FilePath);
FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
Loc = SourceMgr.getLocForStartOfFile(ID);
Loc = Loc.getLocWithOffset(Message.FileOffset);
}
Diags.Report(Loc, Diags.getCustomDiagID(Level, Message.Message));
}
void exportReplacements(const std::vector<ClangTidyError> &Errors,
raw_ostream &OS) {
tooling::TranslationUnitReplacements TUR;
for (const ClangTidyError &Error : Errors)
TUR.Replacements.insert(TUR.Replacements.end(), Error.Fix.begin(),
Error.Fix.end());
yaml::Output YAML(OS);
YAML << TUR;
void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {
FileManager Files((FileSystemOptions()));
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
DiagnosticConsumer *DiagPrinter =
new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts);
DiagnosticsEngine Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
&*DiagOpts, DiagPrinter);
DiagPrinter->BeginSourceFile(LangOptions());
SourceManager SourceMgr(Diags, Files);
Rewriter Rewrite(SourceMgr, LangOptions());
for (SmallVectorImpl<ClangTidyError>::iterator I = Errors.begin(),
E = Errors.end();
I != E; ++I) {
reportDiagnostic(I->Message, SourceMgr, DiagnosticsEngine::Warning, Diags);
for (unsigned i = 0, e = I->Notes.size(); i != e; ++i) {
reportDiagnostic(I->Notes[i], SourceMgr, DiagnosticsEngine::Note, Diags);
}
tooling::applyAllReplacements(I->Fix, Rewrite);
}
// FIXME: Run clang-format on changes.
if (Fix)
Rewrite.overwriteChangedFiles();
}
} // namespace tidy

View File

@@ -10,76 +10,24 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_H
#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyOptions.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <type_traits>
#include <vector>
#include "ClangTidyDiagnosticConsumer.h"
namespace clang {
class CompilerInstance;
namespace ast_matchers {
class MatchFinder;
}
namespace tooling {
class CompilationDatabase;
}
namespace tidy {
/// \brief Provides access to the \c ClangTidyCheck options via check-local
/// names.
///
/// Methods of this class prepend <tt>CheckName + "."</tt> to translate
/// check-local option names to global option names.
class OptionsView {
public:
/// \brief Initializes the instance using \p CheckName + "." as a prefix.
OptionsView(StringRef CheckName,
const ClangTidyOptions::OptionMap &CheckOptions);
/// \brief Read a named option from the \c Context.
///
/// Reads the option with the check-local name \p LocalName from the
/// \c CheckOptions. If the corresponding key is not present, returns
/// \p Default.
std::string get(StringRef LocalName, std::string Default) const;
/// \brief Read a named option from the \c Context and parse it as an integral
/// type \c T.
///
/// Reads the option with the check-local name \p LocalName from the
/// \c CheckOptions. If the corresponding key is not present, returns
/// \p Default.
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
get(StringRef LocalName, T Default) const {
std::string Value = get(LocalName, "");
T Result = Default;
if (!Value.empty())
StringRef(Value).getAsInteger(10, Result);
return Result;
}
/// \brief Stores an option with the check-local name \p LocalName with string
/// value \p Value to \p Options.
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
StringRef Value) const;
/// \brief Stores an option with the check-local name \p LocalName with
/// \c int64_t value \p Value to \p Options.
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
int64_t Value) const;
private:
std::string NamePrefix;
const ClangTidyOptions::OptionMap &CheckOptions;
};
/// \brief Base class for all clang-tidy checks.
///
/// To implement a \c ClangTidyCheck, write a subclass and overwrite some of the
@@ -101,18 +49,6 @@ private:
/// useful/necessary.
class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
public:
/// \brief Initializes the check with \p CheckName and \p Context.
///
/// Derived classes must implement the constructor with this signature or
/// delegate it. If a check needs to read options, it can do this in the
/// constructor using the Options.get() methods below.
ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
: CheckName(CheckName), Context(Context),
Options(CheckName, Context->getOptions().CheckOptions) {
assert(Context != nullptr);
assert(!CheckName.empty());
}
virtual ~ClangTidyCheck() {}
/// \brief Overwrite this to register \c PPCallbacks with \c Compiler.
@@ -139,85 +75,33 @@ public:
/// work in here.
virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}
/// \brief Add a diagnostic with the check's name.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
/// \brief Should store all options supported by this check with their
/// current values or default values for options that haven't been overridden.
///
/// The check should use \c Options.store() to store each option it supports
/// whether it has the default value or it has been overridden.
virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}
private:
void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
StringRef getID() const override { return CheckName; }
std::string CheckName;
ClangTidyContext *Context;
/// \brief The infrastructure sets the context to \p Ctx with this function.
void setContext(ClangTidyContext *Ctx) { Context = Ctx; }
protected:
OptionsView Options;
};
class ClangTidyCheckFactories;
class ClangTidyASTConsumerFactory {
public:
ClangTidyASTConsumerFactory(ClangTidyContext &Context);
/// \brief Returns an ASTConsumer that runs the specified clang-tidy checks.
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler, StringRef File);
/// \brief Get the list of enabled checks.
std::vector<std::string> getCheckNames();
/// \brief Get the union of options from all checks.
ClangTidyOptions::OptionMap getCheckOptions();
ClangTidyContext *Context;
private:
typedef std::vector<std::pair<std::string, bool>> CheckersList;
CheckersList getCheckersControlList(GlobList &Filter);
ClangTidyContext &Context;
std::unique_ptr<ClangTidyCheckFactories> CheckFactories;
virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
};
/// \brief Fills the list of check names that are enabled when the provided
/// filters are applied.
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options);
/// \brief Returns the effective check-specific options.
///
/// The method configures ClangTidy with the specified \p Options and collects
/// effective options from all created checks. The returned set of options
/// includes default check-specific options for all keys not overridden by \p
/// Options.
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options);
/// \brief Returns an action factory that runs the specified clang-tidy checks.
tooling::FrontendActionFactory *
createClangTidyActionFactory(StringRef CheckRegexString,
ClangTidyContext &Context);
/// \brief Run a set of clang-tidy checks on a set of files.
///
/// \param Profile if provided, it enables check profile collection in
/// MatchFinder, and will contain the result of the profile.
ClangTidyStats
runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> InputFiles,
std::vector<ClangTidyError> *Errors,
ProfileData *Profile = nullptr);
void runClangTidy(StringRef CheckRegexString,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> Ranges,
SmallVectorImpl<ClangTidyError> *Errors);
// FIXME: This interface will need to be significantly extended to be useful.
// FIXME: Implement confidence levels for displaying/fixing errors.
//
/// \brief Displays the found \p Errors to the users. If \p Fix is true, \p
/// Errors containing fixes are automatically applied.
void handleErrors(const std::vector<ClangTidyError> &Errors, bool Fix);
/// \brief Serializes replacements into YAML and writes them to the specified
/// output stream.
void exportReplacements(const std::vector<ClangTidyError> &Errors,
raw_ostream &OS);
void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix);
} // end namespace tidy
} // end namespace clang

View File

@@ -1,425 +0,0 @@
//===--- tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp ----------=== //
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file This file implements ClangTidyDiagnosticConsumer, ClangTidyMessage,
/// ClangTidyContext and ClangTidyError classes.
///
/// This tool uses the Clang Tooling infrastructure, see
/// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
/// for details on setting it up with LLVM source tree.
///
//===----------------------------------------------------------------------===//
#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyOptions.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/DiagnosticRenderer.h"
#include "llvm/ADT/SmallString.h"
#include <set>
#include <tuple>
using namespace clang;
using namespace tidy;
namespace {
class ClangTidyDiagnosticRenderer : public DiagnosticRenderer {
public:
ClangTidyDiagnosticRenderer(const LangOptions &LangOpts,
DiagnosticOptions *DiagOpts,
ClangTidyError &Error)
: DiagnosticRenderer(LangOpts, DiagOpts), Error(Error) {}
protected:
void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag Info) override {
// Remove check name from the message.
// FIXME: Remove this once there's a better way to pass check names than
// appending the check name to the message in ClangTidyContext::diag and
// using getCustomDiagID.
std::string CheckNameInMessage = " [" + Error.CheckName + "]";
if (Message.endswith(CheckNameInMessage))
Message = Message.substr(0, Message.size() - CheckNameInMessage.size());
ClangTidyMessage TidyMessage = Loc.isValid()
? ClangTidyMessage(Message, *SM, Loc)
: ClangTidyMessage(Message);
if (Level == DiagnosticsEngine::Note) {
Error.Notes.push_back(TidyMessage);
return;
}
assert(Error.Message.Message.empty() &&
"Overwriting a diagnostic message");
Error.Message = TidyMessage;
}
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) override {}
void emitCodeContext(SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) override {
assert(Loc.isValid());
for (const auto &FixIt : Hints) {
CharSourceRange Range = FixIt.RemoveRange;
assert(Range.getBegin().isValid() && Range.getEnd().isValid() &&
"Invalid range in the fix-it hint.");
assert(Range.getBegin().isFileID() && Range.getEnd().isFileID() &&
"Only file locations supported in fix-it hints.");
Error.Fix.insert(tooling::Replacement(SM, Range, FixIt.CodeToInsert));
}
}
void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) override {}
void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override {}
void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override {}
void endDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) override {
assert(!Error.Message.Message.empty() && "Message has not been set");
}
private:
ClangTidyError &Error;
};
} // end anonymous namespace
ClangTidyMessage::ClangTidyMessage(StringRef Message)
: Message(Message), FileOffset(0) {}
ClangTidyMessage::ClangTidyMessage(StringRef Message,
const SourceManager &Sources,
SourceLocation Loc)
: Message(Message) {
assert(Loc.isValid() && Loc.isFileID());
FilePath = Sources.getFilename(Loc);
FileOffset = Sources.getFileOffset(Loc);
}
ClangTidyError::ClangTidyError(StringRef CheckName,
ClangTidyError::Level DiagLevel)
: CheckName(CheckName), DiagLevel(DiagLevel) {}
// Returns true if GlobList starts with the negative indicator ('-'), removes it
// from the GlobList.
static bool ConsumeNegativeIndicator(StringRef &GlobList) {
if (GlobList.startswith("-")) {
GlobList = GlobList.substr(1);
return true;
}
return false;
}
// Converts first glob from the comma-separated list of globs to Regex and
// removes it and the trailing comma from the GlobList.
static llvm::Regex ConsumeGlob(StringRef &GlobList) {
StringRef Glob = GlobList.substr(0, GlobList.find(','));
GlobList = GlobList.substr(Glob.size() + 1);
llvm::SmallString<128> RegexText("^");
StringRef MetaChars("()^$|*+?.[]\\{}");
for (char C : Glob) {
if (C == '*')
RegexText.push_back('.');
else if (MetaChars.find(C) != StringRef::npos)
RegexText.push_back('\\');
RegexText.push_back(C);
}
RegexText.push_back('$');
return llvm::Regex(RegexText);
}
GlobList::GlobList(StringRef Globs)
: Positive(!ConsumeNegativeIndicator(Globs)),
Regex(ConsumeGlob(Globs)),
NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {}
bool GlobList::contains(StringRef S, bool Contains) {
if (Regex.match(S))
Contains = Positive;
if (NextGlob)
Contains = NextGlob->contains(S, Contains);
return Contains;
}
ClangTidyContext::ClangTidyContext(
std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider)
: DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)),
Profile(nullptr) {
// Before the first translation unit we can get errors related to command-line
// parsing, use empty string for the file name in this case.
setCurrentFile("");
}
DiagnosticBuilder ClangTidyContext::diag(
StringRef CheckName, SourceLocation Loc, StringRef Description,
DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
assert(Loc.isValid());
bool Invalid;
const char *CharacterData =
DiagEngine->getSourceManager().getCharacterData(Loc, &Invalid);
if (!Invalid) {
const char *P = CharacterData;
while (*P != '\0' && *P != '\r' && *P != '\n')
++P;
StringRef RestOfLine(CharacterData, P - CharacterData + 1);
// FIXME: Handle /\bNOLINT\b(\([^)]*\))?/ as cpplint.py does.
if (RestOfLine.find("NOLINT") != StringRef::npos) {
Level = DiagnosticIDs::Ignored;
++Stats.ErrorsIgnoredNOLINT;
}
}
unsigned ID = DiagEngine->getDiagnosticIDs()->getCustomDiagID(
Level, (Description + " [" + CheckName + "]").str());
if (CheckNamesByDiagnosticID.count(ID) == 0)
CheckNamesByDiagnosticID.insert(std::make_pair(ID, CheckName.str()));
return DiagEngine->Report(Loc, ID);
}
void ClangTidyContext::setDiagnosticsEngine(DiagnosticsEngine *Engine) {
DiagEngine = Engine;
}
void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
DiagEngine->setSourceManager(SourceMgr);
}
void ClangTidyContext::setCurrentFile(StringRef File) {
CurrentFile = File;
// Safeguard against options with unset values.
CurrentOptions = ClangTidyOptions::getDefaults().mergeWith(
OptionsProvider->getOptions(CurrentFile));
CheckFilter.reset(new GlobList(*getOptions().Checks));
}
void ClangTidyContext::setASTContext(ASTContext *Context) {
DiagEngine->SetArgToStringFn(&FormatASTNodeDiagnosticArgument, Context);
}
const ClangTidyGlobalOptions &ClangTidyContext::getGlobalOptions() const {
return OptionsProvider->getGlobalOptions();
}
const ClangTidyOptions &ClangTidyContext::getOptions() const {
return CurrentOptions;
}
void ClangTidyContext::setCheckProfileData(ProfileData *P) {
Profile = P;
}
GlobList &ClangTidyContext::getChecksFilter() {
assert(CheckFilter != nullptr);
return *CheckFilter;
}
/// \brief Store a \c ClangTidyError.
void ClangTidyContext::storeError(const ClangTidyError &Error) {
Errors.push_back(Error);
}
StringRef ClangTidyContext::getCheckName(unsigned DiagnosticID) const {
llvm::DenseMap<unsigned, std::string>::const_iterator I =
CheckNamesByDiagnosticID.find(DiagnosticID);
if (I != CheckNamesByDiagnosticID.end())
return I->second;
return "";
}
ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx)
: Context(Ctx), LastErrorRelatesToUserCode(false),
LastErrorPassesLineFilter(false) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
Diags.reset(new DiagnosticsEngine(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts, this,
/*ShouldOwnClient=*/false));
Context.setDiagnosticsEngine(Diags.get());
}
void ClangTidyDiagnosticConsumer::finalizeLastError() {
if (!Errors.empty()) {
ClangTidyError &Error = Errors.back();
if (!Context.getChecksFilter().contains(Error.CheckName) &&
Error.DiagLevel != ClangTidyError::Error) {
++Context.Stats.ErrorsIgnoredCheckFilter;
Errors.pop_back();
} else if (!LastErrorRelatesToUserCode) {
++Context.Stats.ErrorsIgnoredNonUserCode;
Errors.pop_back();
} else if (!LastErrorPassesLineFilter) {
++Context.Stats.ErrorsIgnoredLineFilter;
Errors.pop_back();
} else {
++Context.Stats.ErrorsDisplayed;
}
}
LastErrorRelatesToUserCode = false;
LastErrorPassesLineFilter = false;
}
void ClangTidyDiagnosticConsumer::HandleDiagnostic(
DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
// Count warnings/errors.
DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
if (DiagLevel == DiagnosticsEngine::Note) {
assert(!Errors.empty() &&
"A diagnostic note can only be appended to a message.");
} else {
finalizeLastError();
StringRef WarningOption =
Context.DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(
Info.getID());
std::string CheckName = !WarningOption.empty()
? ("clang-diagnostic-" + WarningOption).str()
: Context.getCheckName(Info.getID()).str();
if (CheckName.empty()) {
// This is a compiler diagnostic without a warning option. Assign check
// name based on its level.
switch (DiagLevel) {
case DiagnosticsEngine::Error:
case DiagnosticsEngine::Fatal:
CheckName = "clang-diagnostic-error";
break;
case DiagnosticsEngine::Warning:
CheckName = "clang-diagnostic-warning";
break;
default:
CheckName = "clang-diagnostic-unknown";
break;
}
}
ClangTidyError::Level Level = ClangTidyError::Warning;
if (DiagLevel == DiagnosticsEngine::Error ||
DiagLevel == DiagnosticsEngine::Fatal) {
// Force reporting of Clang errors regardless of filters and non-user
// code.
Level = ClangTidyError::Error;
LastErrorRelatesToUserCode = true;
LastErrorPassesLineFilter = true;
}
Errors.push_back(ClangTidyError(CheckName, Level));
}
// FIXME: Provide correct LangOptions for each file.
LangOptions LangOpts;
ClangTidyDiagnosticRenderer Converter(
LangOpts, &Context.DiagEngine->getDiagnosticOptions(), Errors.back());
SmallString<100> Message;
Info.FormatDiagnostic(Message);
SourceManager *Sources = nullptr;
if (Info.hasSourceManager())
Sources = &Info.getSourceManager();
Converter.emitDiagnostic(Info.getLocation(), DiagLevel, Message,
Info.getRanges(), Info.getFixItHints(), Sources);
checkFilters(Info.getLocation());
}
void ClangTidyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts,
const Preprocessor *PP) {
// Before the first translation unit we don't need HeaderFilter, as we
// shouldn't get valid source locations in diagnostics.
HeaderFilter.reset(new llvm::Regex(*Context.getOptions().HeaderFilterRegex));
}
bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName,
unsigned LineNumber) const {
if (Context.getGlobalOptions().LineFilter.empty())
return true;
for (const FileFilter& Filter : Context.getGlobalOptions().LineFilter) {
if (FileName.endswith(Filter.Name)) {
if (Filter.LineRanges.empty())
return true;
for (const FileFilter::LineRange &Range : Filter.LineRanges) {
if (Range.first <= LineNumber && LineNumber <= Range.second)
return true;
}
return false;
}
}
return false;
}
void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location) {
// Invalid location may mean a diagnostic in a command line, don't skip these.
if (!Location.isValid()) {
LastErrorRelatesToUserCode = true;
LastErrorPassesLineFilter = true;
return;
}
const SourceManager &Sources = Diags->getSourceManager();
if (!*Context.getOptions().SystemHeaders &&
Sources.isInSystemHeader(Location))
return;
// FIXME: We start with a conservative approach here, but the actual type of
// location needed depends on the check (in particular, where this check wants
// to apply fixes).
FileID FID = Sources.getDecomposedExpansionLoc(Location).first;
const FileEntry *File = Sources.getFileEntryForID(FID);
// -DMACRO definitions on the command line have locations in a virtual buffer
// that doesn't have a FileEntry. Don't skip these as well.
if (!File) {
LastErrorRelatesToUserCode = true;
LastErrorPassesLineFilter = true;
return;
}
StringRef FileName(File->getName());
assert(LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
HeaderFilter != nullptr);
LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
HeaderFilter->match(FileName);
unsigned LineNumber = Sources.getExpansionLineNumber(Location);
LastErrorPassesLineFilter =
LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
}
namespace {
struct LessClangTidyError {
bool operator()(const ClangTidyError *LHS, const ClangTidyError *RHS) const {
const ClangTidyMessage &M1 = LHS->Message;
const ClangTidyMessage &M2 = RHS->Message;
return std::tie(M1.FilePath, M1.FileOffset, M1.Message) <
std::tie(M2.FilePath, M2.FileOffset, M2.Message);
}
};
} // end anonymous namespace
// Flushes the internal diagnostics buffer to the ClangTidyContext.
void ClangTidyDiagnosticConsumer::finish() {
finalizeLastError();
std::set<const ClangTidyError*, LessClangTidyError> UniqueErrors;
for (const ClangTidyError &Error : Errors)
UniqueErrors.insert(&Error);
for (const ClangTidyError *Error : UniqueErrors)
Context.storeError(*Error);
Errors.clear();
}

View File

@@ -10,18 +10,13 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
#include "ClangTidyOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/Timer.h"
#include "llvm/ADT/SmallString.h"
namespace clang {
class ASTContext;
class CompilerInstance;
namespace ast_matchers {
class MatchFinder;
@@ -52,67 +47,14 @@ struct ClangTidyMessage {
///
/// FIXME: Make Diagnostics flexible enough to support this directly.
struct ClangTidyError {
enum Level {
Warning = DiagnosticsEngine::Warning,
Error = DiagnosticsEngine::Error
};
ClangTidyError(const ClangTidyMessage &Message);
ClangTidyError(StringRef CheckName, Level DiagLevel);
std::string CheckName;
ClangTidyMessage Message;
tooling::Replacements Fix;
SmallVector<ClangTidyMessage, 1> Notes;
Level DiagLevel;
};
/// \brief Read-only set of strings represented as a list of positive and
/// negative globs. Positive globs add all matched strings to the set, negative
/// globs remove them in the order of appearance in the list.
class GlobList {
public:
/// \brief \p GlobList is a comma-separated list of globs (only '*'
/// metacharacter is supported) with optional '-' prefix to denote exclusion.
GlobList(StringRef Globs);
/// \brief Returns \c true if the pattern matches \p S. The result is the last
/// matching glob's Positive flag.
bool contains(StringRef S) { return contains(S, false); }
private:
bool contains(StringRef S, bool Contains);
bool Positive;
llvm::Regex Regex;
std::unique_ptr<GlobList> NextGlob;
};
/// \brief Contains displayed and ignored diagnostic counters for a ClangTidy
/// run.
struct ClangTidyStats {
ClangTidyStats()
: ErrorsDisplayed(0), ErrorsIgnoredCheckFilter(0), ErrorsIgnoredNOLINT(0),
ErrorsIgnoredNonUserCode(0), ErrorsIgnoredLineFilter(0) {}
unsigned ErrorsDisplayed;
unsigned ErrorsIgnoredCheckFilter;
unsigned ErrorsIgnoredNOLINT;
unsigned ErrorsIgnoredNonUserCode;
unsigned ErrorsIgnoredLineFilter;
unsigned errorsIgnored() const {
return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
}
};
/// \brief Container for clang-tidy profiling data.
struct ProfileData {
llvm::StringMap<llvm::TimeRecord> Records;
};
/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
/// provided by this context.
///
/// A \c ClangTidyCheck always has access to the active context to report
@@ -123,83 +65,34 @@ struct ProfileData {
/// \endcode
class ClangTidyContext {
public:
/// \brief Initializes \c ClangTidyContext instance.
ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider);
ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors) : Errors(Errors) {}
/// \brief Report any errors detected using this method.
///
/// This is still under heavy development and will likely change towards using
/// tablegen'd diagnostic IDs.
/// FIXME: Figure out a way to manage ID spaces.
DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
StringRef Message,
DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
DiagnosticBuilder Diag(SourceLocation Loc, StringRef Message);
/// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
/// correctly.
///
/// This is called from the \c ClangTidyCheck base class.
void setDiagnosticsEngine(DiagnosticsEngine *Engine);
/// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
///
/// This is called from the \c ClangTidyCheck base class.
void setSourceManager(SourceManager *SourceMgr);
/// \brief Should be called when starting to process new translation unit.
void setCurrentFile(StringRef File);
/// \brief Sets ASTContext for the current translation unit.
void setASTContext(ASTContext *Context);
/// \brief Returns the name of the clang-tidy check which produced this
/// diagnostic ID.
StringRef getCheckName(unsigned DiagnosticID) const;
/// \brief Returns check filter for the \c CurrentFile.
GlobList &getChecksFilter();
/// \brief Returns global options.
const ClangTidyGlobalOptions &getGlobalOptions() const;
/// \brief Returns options for \c CurrentFile.
const ClangTidyOptions &getOptions() const;
/// \brief Returns \c ClangTidyStats containing issued and ignored diagnostic
/// counters.
const ClangTidyStats &getStats() const { return Stats; }
/// \brief Returns all collected errors.
const std::vector<ClangTidyError> &getErrors() const { return Errors; }
/// \brief Clears collected errors.
void clearErrors() { Errors.clear(); }
/// \brief Set the output struct for profile data.
///
/// Setting a non-null pointer here will enable profile collection in
/// clang-tidy.
void setCheckProfileData(ProfileData* Profile);
ProfileData* getCheckProfileData() const { return Profile; }
private:
// Calls setDiagnosticsEngine() and storeError().
friend class ClangTidyDiagnosticConsumer;
friend class ClangTidyDiagnosticConsumer; // Calls storeError().
/// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
/// correctly.
void setDiagnosticsEngine(DiagnosticsEngine *Engine);
/// \brief Store an \p Error.
/// \brief Store a \c ClangTidyError.
void storeError(const ClangTidyError &Error);
std::vector<ClangTidyError> Errors;
SmallVectorImpl<ClangTidyError> *Errors;
DiagnosticsEngine *DiagEngine;
std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
std::string CurrentFile;
ClangTidyOptions CurrentOptions;
std::unique_ptr<GlobList> CheckFilter;
ClangTidyStats Stats;
llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
ProfileData *Profile;
};
/// \brief A diagnostic consumer that turns each \c Diagnostic into a
@@ -209,35 +102,59 @@ private:
// implementation file.
class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
public:
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx);
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx) : Context(Ctx) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
Diags.reset(new DiagnosticsEngine(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts, this,
/*ShouldOwnClient=*/false));
Context.setDiagnosticsEngine(Diags.get());
}
// FIXME: The concept of converting between FixItHints and Replacements is
// more generic and should be pulled out into a more useful Diagnostics
// library.
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override;
virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) {
if (DiagLevel != DiagnosticsEngine::Note) {
Errors.push_back(ClangTidyError(getMessage(Info)));
} else {
Errors.back().Notes.push_back(getMessage(Info));
}
addFixes(Info, Errors.back());
}
/// \brief Sets \c HeaderFilter to the value configured for this file.
void BeginSourceFile(const LangOptions &LangOpts,
const Preprocessor *PP) override;
/// \brief Flushes the internal diagnostics buffer to the ClangTidyContext.
void finish() override;
virtual void finish() {
for (unsigned i = 0, e = Errors.size(); i != e; ++i) {
Context.storeError(Errors[i]);
}
}
private:
void finalizeLastError();
void addFixes(const Diagnostic &Info, ClangTidyError &Error) {
if (!Info.hasSourceManager())
return;
SourceManager &SourceMgr = Info.getSourceManager();
tooling::Replacements Replacements;
for (unsigned i = 0, e = Info.getNumFixItHints(); i != e; ++i) {
Error.Fix.insert(tooling::Replacement(
SourceMgr, Info.getFixItHint(i).RemoveRange.getBegin(), 0,
Info.getFixItHint(i).CodeToInsert));
}
}
/// \brief Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
/// according to the diagnostic \p Location.
void checkFilters(SourceLocation Location);
bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
ClangTidyMessage getMessage(const Diagnostic &Info) const {
SmallString<100> Buf;
Info.FormatDiagnostic(Buf);
if (!Info.hasSourceManager()) {
return ClangTidyMessage(Buf.str());
}
return ClangTidyMessage(Buf.str(), Info.getSourceManager(),
Info.getLocation());
}
ClangTidyContext &Context;
std::unique_ptr<DiagnosticsEngine> Diags;
OwningPtr<DiagnosticsEngine> Diags;
SmallVector<ClangTidyError, 8> Errors;
std::unique_ptr<llvm::Regex> HeaderFilter;
bool LastErrorRelatesToUserCode;
bool LastErrorPassesLineFilter;
};
} // end namespace tidy

View File

@@ -12,28 +12,38 @@
//===----------------------------------------------------------------------===//
#include "ClangTidyModule.h"
#include "llvm/Support/Regex.h"
namespace clang {
namespace tidy {
void ClangTidyCheckFactories::registerCheckFactory(StringRef Name,
CheckFactory Factory) {
CheckFactoryBase::~CheckFactoryBase() {}
ClangTidyCheckFactories::~ClangTidyCheckFactories() {
for (std::map<std::string, CheckFactoryBase *>::iterator
I = Factories.begin(),
E = Factories.end();
I != E; ++I) {
delete I->second;
}
}
void ClangTidyCheckFactories::addCheckFactory(StringRef Name,
CheckFactoryBase *Factory) {
Factories[Name] = Factory;
}
void ClangTidyCheckFactories::createChecks(
ClangTidyContext *Context,
std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
GlobList &Filter = Context->getChecksFilter();
for (const auto &Factory : Factories) {
if (Filter.contains(Factory.first))
Checks.emplace_back(Factory.second(Factory.first, Context));
StringRef CheckRegexString, SmallVectorImpl<ClangTidyCheck *> &Checks) {
llvm::Regex CheckRegex(CheckRegexString);
for (std::map<std::string, CheckFactoryBase *>::iterator
I = Factories.begin(),
E = Factories.end();
I != E; ++I) {
if (CheckRegex.match(I->first))
Checks.push_back(I->second->createCheck());
}
}
ClangTidyOptions ClangTidyModule::getModuleOptions() {
return ClangTidyOptions();
}
} // namespace tidy
} // namespace clang

View File

@@ -11,73 +11,50 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_MODULE_H
#include "ClangTidy.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <functional>
#include <map>
#include <string>
#include <utility>
namespace clang {
namespace tidy {
/// \brief A collection of \c ClangTidyCheckFactory instances.
/// \brief A factory, that can instantiate a specific clang-tidy check for
/// processing a translation unit.
///
/// All clang-tidy modules register their check factories with an instance of
/// this object.
class ClangTidyCheckFactories {
/// In order to register your check with the \c ClangTidyModule, create a
/// subclass of \c CheckFactoryBase and implement \c createCheck(). Then, use
/// this subclass in \c ClangTidyModule::addCheckFactories().
class CheckFactoryBase {
public:
typedef std::function<ClangTidyCheck *(
StringRef Name, ClangTidyContext *Context)> CheckFactory;
/// \brief Registers check \p Factory with name \p Name.
///
/// For all checks that have default constructors, use \c registerCheck.
void registerCheckFactory(StringRef Name, CheckFactory Factory);
/// \brief Registers the \c CheckType with the name \p Name.
///
/// This method should be used for all \c ClangTidyChecks that don't require
/// constructor parameters.
///
/// For example, if have a clang-tidy check like:
/// \code
/// class MyTidyCheck : public ClangTidyCheck {
/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
/// ..
/// }
/// };
/// \endcode
/// you can register it with:
/// \code
/// class MyModule : public ClangTidyModule {
/// void addCheckFactories(ClangTidyCheckFactories &Factories) override {
/// Factories.registerCheck<MyTidyCheck>("myproject-my-check");
/// }
/// };
/// \endcode
template <typename CheckType> void registerCheck(StringRef CheckName) {
registerCheckFactory(CheckName,
[](StringRef Name, ClangTidyContext *Context) {
return new CheckType(Name, Context);
});
}
/// \brief Create instances of all checks matching \p CheckRegexString and
/// store them in \p Checks.
///
/// The caller takes ownership of the return \c ClangTidyChecks.
void createChecks(ClangTidyContext *Context,
std::vector<std::unique_ptr<ClangTidyCheck>> &Checks);
typedef std::map<std::string, CheckFactory> FactoryMap;
FactoryMap::const_iterator begin() const { return Factories.begin(); }
FactoryMap::const_iterator end() const { return Factories.end(); }
bool empty() const { return Factories.empty(); }
private:
FactoryMap Factories;
virtual ~CheckFactoryBase();
virtual ClangTidyCheck *createCheck() = 0;
};
/// \brief A subclass of \c CheckFactoryBase that should be used for all
/// \c ClangTidyChecks that don't require constructor parameters.
///
/// For example, if have a clang-tidy check like:
/// \code
/// class MyTidyCheck : public ClangTidyCheck {
/// virtual void registerMatchers(ast_matchers::MatchFinder *Finder) { .. }
/// };
/// \endcode
/// you can register it with:
/// \code
/// class MyModule : public ClangTidyModule {
/// virtual void addCheckFactories(ClangTidyCheckFactories &CheckFactories) {
/// CheckFactories.addCheckFactory(
/// "myproject-my-check", new ClangTidyCheckFactory<MyTidyCheck>());
/// }
/// };
/// \endcode
template <typename T> class ClangTidyCheckFactory : public CheckFactoryBase {
public:
virtual ClangTidyCheck *createCheck() { return new T; }
};
class ClangTidyCheckFactories;
/// \brief A clang-tidy module groups a number of \c ClangTidyChecks and gives
/// them a prefixed name.
class ClangTidyModule {
@@ -87,9 +64,32 @@ public:
/// \brief Implement this function in order to register all \c CheckFactories
/// belonging to this module.
virtual void addCheckFactories(ClangTidyCheckFactories &CheckFactories) = 0;
};
/// \brief Gets default options for checks defined in this module.
virtual ClangTidyOptions getModuleOptions();
/// \brief A collection of \c ClangTidyCheckFactory instances.
///
/// All clang-tidy modules register their check factories with an instance of
/// this object.
class ClangTidyCheckFactories {
public:
ClangTidyCheckFactories() {}
~ClangTidyCheckFactories();
/// \brief Register \p Factory with the name \p Name.
///
/// The \c ClangTidyCheckFactories object takes ownership of the \p Factory.
void addCheckFactory(StringRef Name, CheckFactoryBase *Factory);
/// \brief Create instances of all checks matching \p CheckRegexString and
/// store them in \p Checks.
///
/// The caller takes ownership of the return \c ClangTidyChecks.
void createChecks(StringRef CheckRegexString,
SmallVectorImpl<ClangTidyCheck *> &Checks);
private:
StringRef FilterRegex;
std::map<std::string, CheckFactoryBase *> Factories;
};
} // end namespace tidy

View File

@@ -13,8 +13,6 @@
#include "ClangTidyModule.h"
#include "llvm/Support/Registry.h"
extern template class llvm::Registry<clang::tidy::ClangTidyModule>;
namespace clang {
namespace tidy {

View File

@@ -1,281 +0,0 @@
//===--- ClangTidyOptions.cpp - clang-tidy ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ClangTidyOptions.h"
#include "ClangTidyModuleRegistry.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>
#define DEBUG_TYPE "clang-tidy-options"
using clang::tidy::ClangTidyOptions;
using clang::tidy::FileFilter;
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter::LineRange)
LLVM_YAML_IS_SEQUENCE_VECTOR(ClangTidyOptions::StringPair)
namespace llvm {
namespace yaml {
// Map std::pair<int, int> to a JSON array of size 2.
template <> struct SequenceTraits<FileFilter::LineRange> {
static size_t size(IO &IO, FileFilter::LineRange &Range) {
return Range.first == 0 ? 0 : Range.second == 0 ? 1 : 2;
}
static unsigned &element(IO &IO, FileFilter::LineRange &Range, size_t Index) {
if (Index > 1)
IO.setError("Too many elements in line range.");
return Index == 0 ? Range.first : Range.second;
}
};
template <> struct MappingTraits<FileFilter> {
static void mapping(IO &IO, FileFilter &File) {
IO.mapRequired("name", File.Name);
IO.mapOptional("lines", File.LineRanges);
}
static StringRef validate(IO &io, FileFilter &File) {
if (File.Name.empty())
return "No file name specified";
for (const FileFilter::LineRange &Range : File.LineRanges) {
if (Range.first <= 0 || Range.second <= 0)
return "Invalid line range";
}
return StringRef();
}
};
template <> struct MappingTraits<ClangTidyOptions::StringPair> {
static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) {
IO.mapRequired("key", KeyValue.first);
IO.mapRequired("value", KeyValue.second);
}
};
struct NOptionMap {
NOptionMap(IO &) {}
NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap)
: Options(OptionMap.begin(), OptionMap.end()) {}
ClangTidyOptions::OptionMap denormalize(IO &) {
ClangTidyOptions::OptionMap Map;
for (const auto &KeyValue : Options)
Map[KeyValue.first] = KeyValue.second;
return Map;
}
std::vector<ClangTidyOptions::StringPair> Options;
};
template <> struct MappingTraits<ClangTidyOptions> {
static void mapping(IO &IO, ClangTidyOptions &Options) {
MappingNormalization<NOptionMap, ClangTidyOptions::OptionMap> NOpts(
IO, Options.CheckOptions);
IO.mapOptional("Checks", Options.Checks);
IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
IO.mapOptional("AnalyzeTemporaryDtors", Options.AnalyzeTemporaryDtors);
IO.mapOptional("User", Options.User);
IO.mapOptional("CheckOptions", NOpts->Options);
}
};
} // namespace yaml
} // namespace llvm
namespace clang {
namespace tidy {
ClangTidyOptions ClangTidyOptions::getDefaults() {
ClangTidyOptions Options;
Options.Checks = "";
Options.HeaderFilterRegex = "";
Options.SystemHeaders = false;
Options.AnalyzeTemporaryDtors = false;
Options.User = llvm::None;
for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
E = ClangTidyModuleRegistry::end();
I != E; ++I)
Options = Options.mergeWith(I->instantiate()->getModuleOptions());
return Options;
}
ClangTidyOptions
ClangTidyOptions::mergeWith(const ClangTidyOptions &Other) const {
ClangTidyOptions Result = *this;
// Merge comma-separated glob lists by appending the new value after a comma.
if (Other.Checks)
Result.Checks =
(Result.Checks && !Result.Checks->empty() ? *Result.Checks + "," : "") +
*Other.Checks;
if (Other.HeaderFilterRegex)
Result.HeaderFilterRegex = Other.HeaderFilterRegex;
if (Other.SystemHeaders)
Result.SystemHeaders = Other.SystemHeaders;
if (Other.AnalyzeTemporaryDtors)
Result.AnalyzeTemporaryDtors = Other.AnalyzeTemporaryDtors;
if (Other.User)
Result.User = Other.User;
for (const auto &KeyValue : Other.CheckOptions)
Result.CheckOptions[KeyValue.first] = KeyValue.second;
return Result;
}
FileOptionsProvider::FileOptionsProvider(
const ClangTidyGlobalOptions &GlobalOptions,
const ClangTidyOptions &DefaultOptions,
const ClangTidyOptions &OverrideOptions)
: DefaultOptionsProvider(GlobalOptions, DefaultOptions),
OverrideOptions(OverrideOptions) {
ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration);
CachedOptions[""] = DefaultOptions.mergeWith(OverrideOptions);
}
FileOptionsProvider::FileOptionsProvider(
const ClangTidyGlobalOptions &GlobalOptions,
const ClangTidyOptions &DefaultOptions,
const ClangTidyOptions &OverrideOptions,
const FileOptionsProvider::ConfigFileHandlers &ConfigHandlers)
: DefaultOptionsProvider(GlobalOptions, DefaultOptions),
OverrideOptions(OverrideOptions), ConfigHandlers(ConfigHandlers) {
CachedOptions[""] = DefaultOptions.mergeWith(OverrideOptions);
}
// FIXME: This method has some common logic with clang::format::getStyle().
// Consider pulling out common bits to a findParentFileWithName function or
// similar.
const ClangTidyOptions &FileOptionsProvider::getOptions(StringRef FileName) {
DEBUG(llvm::dbgs() << "Getting options for file " << FileName << "...\n");
SmallString<256> FilePath(FileName);
if (std::error_code EC = llvm::sys::fs::make_absolute(FilePath)) {
llvm::errs() << "Can't make absolute path from " << FileName << ": "
<< EC.message() << "\n";
// FIXME: Figure out what to do.
} else {
FileName = FilePath;
}
// Look for a suitable configuration file in all parent directories of the
// file. Start with the immediate parent directory and move up.
StringRef Path = llvm::sys::path::parent_path(FileName);
for (StringRef CurrentPath = Path;;
CurrentPath = llvm::sys::path::parent_path(CurrentPath)) {
llvm::Optional<ClangTidyOptions> Result;
auto Iter = CachedOptions.find(CurrentPath);
if (Iter != CachedOptions.end())
Result = Iter->second;
if (!Result)
Result = TryReadConfigFile(CurrentPath);
if (Result) {
// Store cached value for all intermediate directories.
while (Path != CurrentPath) {
DEBUG(llvm::dbgs() << "Caching configuration for path " << Path
<< ".\n");
CachedOptions[Path] = *Result;
Path = llvm::sys::path::parent_path(Path);
}
return CachedOptions[Path] = *Result;
}
}
}
llvm::Optional<ClangTidyOptions>
FileOptionsProvider::TryReadConfigFile(StringRef Directory) {
assert(!Directory.empty());
if (!llvm::sys::fs::is_directory(Directory)) {
llvm::errs() << "Error reading configuration from " << Directory
<< ": directory doesn't exist.\n";
return llvm::None;
}
for (const ConfigFileHandler &ConfigHandler : ConfigHandlers) {
SmallString<128> ConfigFile(Directory);
llvm::sys::path::append(ConfigFile, ConfigHandler.first);
DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
bool IsFile = false;
// Ignore errors from is_regular_file: we only need to know if we can read
// the file or not.
llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
if (!IsFile)
continue;
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
llvm::MemoryBuffer::getFile(ConfigFile.c_str());
if (std::error_code EC = Text.getError()) {
llvm::errs() << "Can't read " << ConfigFile << ": " << EC.message()
<< "\n";
continue;
}
// Skip empty files, e.g. files opened for writing via shell output
// redirection.
if ((*Text)->getBuffer().empty())
continue;
llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
ConfigHandler.second((*Text)->getBuffer());
if (!ParsedOptions) {
if (ParsedOptions.getError())
llvm::errs() << "Error parsing " << ConfigFile << ": "
<< ParsedOptions.getError().message() << "\n";
continue;
}
ClangTidyOptions Defaults = DefaultOptionsProvider::getOptions(Directory);
// Only use checks from the config file.
Defaults.Checks = None;
return Defaults.mergeWith(*ParsedOptions).mergeWith(OverrideOptions);
}
return llvm::None;
}
/// \brief Parses -line-filter option and stores it to the \c Options.
std::error_code parseLineFilter(StringRef LineFilter,
clang::tidy::ClangTidyGlobalOptions &Options) {
llvm::yaml::Input Input(LineFilter);
Input >> Options.LineFilter;
return Input.error();
}
llvm::ErrorOr<ClangTidyOptions> parseConfiguration(StringRef Config) {
llvm::yaml::Input Input(Config);
ClangTidyOptions Options;
Input >> Options;
if (Input.error())
return Input.error();
return Options;
}
std::string configurationAsText(const ClangTidyOptions &Options) {
std::string Text;
llvm::raw_string_ostream Stream(Text);
llvm::yaml::Output Output(Stream);
// We use the same mapping method for input and output, so we need a non-const
// reference here.
ClangTidyOptions NonConstValue = Options;
Output << NonConstValue;
return Stream.str();
}
} // namespace tidy
} // namespace clang

View File

@@ -1,216 +0,0 @@
//===--- ClangTidyOptions.h - clang-tidy ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorOr.h"
#include <functional>
#include <map>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
namespace clang {
namespace tidy {
/// \brief Contains a list of line ranges in a single file.
struct FileFilter {
/// \brief File name.
std::string Name;
/// \brief LineRange is a pair<start, end> (inclusive).
typedef std::pair<unsigned, unsigned> LineRange;
/// \brief A list of line ranges in this file, for which we show warnings.
std::vector<LineRange> LineRanges;
};
/// \brief Global options. These options are neither stored nor read from
/// configuration files.
struct ClangTidyGlobalOptions {
/// \brief Output warnings from certain line ranges of certain files only.
/// If empty, no warnings will be filtered.
std::vector<FileFilter> LineFilter;
};
/// \brief Contains options for clang-tidy. These options may be read from
/// configuration files, and may be different for different translation units.
struct ClangTidyOptions {
/// \brief These options are used for all settings that haven't been
/// overridden by the \c OptionsProvider.
///
/// Allow no checks and no headers by default. This method initializes
/// check-specific options by calling \c ClangTidyModule::getModuleOptions()
/// of each registered \c ClangTidyModule.
static ClangTidyOptions getDefaults();
/// \brief Creates a new \c ClangTidyOptions instance combined from all fields
/// of this instance overridden by the fields of \p Other that have a value.
ClangTidyOptions mergeWith(const ClangTidyOptions &Other) const;
/// \brief Checks filter.
llvm::Optional<std::string> Checks;
/// \brief Output warnings from headers matching this filter. Warnings from
/// main files will always be displayed.
llvm::Optional<std::string> HeaderFilterRegex;
/// \brief Output warnings from system headers matching \c HeaderFilterRegex.
llvm::Optional<bool> SystemHeaders;
/// \brief Turns on temporary destructor-based analysis.
llvm::Optional<bool> AnalyzeTemporaryDtors;
/// \brief Specifies the name or e-mail of the user running clang-tidy.
///
/// This option is used, for example, to place the correct user name in TODO()
/// comments in the relevant check.
llvm::Optional<std::string> User;
typedef std::pair<std::string, std::string> StringPair;
typedef std::map<std::string, std::string> OptionMap;
/// \brief Key-value mapping used to store check-specific options.
OptionMap CheckOptions;
};
/// \brief Abstract interface for retrieving various ClangTidy options.
class ClangTidyOptionsProvider {
public:
virtual ~ClangTidyOptionsProvider() {}
/// \brief Returns global options, which are independent of the file.
virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0;
/// \brief Returns options applying to a specific translation unit with the
/// specified \p FileName.
virtual const ClangTidyOptions &getOptions(llvm::StringRef FileName) = 0;
};
/// \brief Implementation of the \c ClangTidyOptionsProvider interface, which
/// returns the same options for all files.
class DefaultOptionsProvider : public ClangTidyOptionsProvider {
public:
DefaultOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions,
const ClangTidyOptions &Options)
: GlobalOptions(GlobalOptions), DefaultOptions(Options) {}
const ClangTidyGlobalOptions &getGlobalOptions() override {
return GlobalOptions;
}
const ClangTidyOptions &getOptions(llvm::StringRef /*FileName*/) override {
return DefaultOptions;
}
private:
ClangTidyGlobalOptions GlobalOptions;
ClangTidyOptions DefaultOptions;
};
/// \brief Implementation of the \c ClangTidyOptionsProvider interface, which
/// tries to find a configuration file in the closest parent directory of each
/// source file.
///
/// By default, files named ".clang-tidy" will be considered, and the
/// \c clang::tidy::parseConfiguration function will be used for parsing, but a
/// custom set of configuration file names and parsing functions can be
/// specified using the appropriate constructor.
class FileOptionsProvider : public DefaultOptionsProvider {
public:
// \brief A pair of configuration file base name and a function parsing
// configuration from text in the corresponding format.
typedef std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>(
llvm::StringRef)>> ConfigFileHandler;
/// \brief Configuration file handlers listed in the order of priority.
///
/// Custom configuration file formats can be supported by constructing the
/// list of handlers and passing it to the appropriate \c FileOptionsProvider
/// constructor. E.g. initialization of a \c FileOptionsProvider with support
/// of a custom configuration file format for files named ".my-tidy-config"
/// could look similar to this:
/// \code
/// FileOptionsProvider::ConfigFileHandlers ConfigHandlers;
/// ConfigHandlers.emplace_back(".my-tidy-config", parseMyConfigFormat);
/// ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration);
/// return llvm::make_unique<FileOptionsProvider>(
/// GlobalOptions, DefaultOptions, OverrideOptions, ConfigHandlers);
/// \endcode
///
/// With the order of handlers shown above, the ".my-tidy-config" file would
/// take precedence over ".clang-tidy" if both reside in the same directory.
typedef std::vector<ConfigFileHandler> ConfigFileHandlers;
/// \brief Initializes the \c FileOptionsProvider instance.
///
/// \param GlobalOptions are just stored and returned to the caller of
/// \c getGlobalOptions.
///
/// \param DefaultOptions are used for all settings not specified in a
/// configuration file.
///
/// If any of the \param OverrideOptions fields are set, they will override
/// whatever options are read from the configuration file.
FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions,
const ClangTidyOptions &DefaultOptions,
const ClangTidyOptions &OverrideOptions);
/// \brief Initializes the \c FileOptionsProvider instance with a custom set
/// of configuration file handlers.
///
/// \param GlobalOptions are just stored and returned to the caller of
/// \c getGlobalOptions.
///
/// \param DefaultOptions are used for all settings not specified in a
/// configuration file.
///
/// If any of the \param OverrideOptions fields are set, they will override
/// whatever options are read from the configuration file.
///
/// \param ConfigHandlers specifies a custom set of configuration file
/// handlers. Each handler is a pair of configuration file name and a function
/// that can parse configuration from this file type. The configuration files
/// in each directory are searched for in the order of appearance in
/// \p ConfigHandlers.
FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions,
const ClangTidyOptions &DefaultOptions,
const ClangTidyOptions &OverrideOptions,
const ConfigFileHandlers &ConfigHandlers);
const ClangTidyOptions &getOptions(llvm::StringRef FileName) override;
private:
/// \brief Try to read configuration files from \p Directory using registered
/// \c ConfigHandlers.
llvm::Optional<ClangTidyOptions> TryReadConfigFile(llvm::StringRef Directory);
llvm::StringMap<ClangTidyOptions> CachedOptions;
ClangTidyOptions OverrideOptions;
ConfigFileHandlers ConfigHandlers;
};
/// \brief Parses LineFilter from JSON and stores it to the \p Options.
std::error_code parseLineFilter(llvm::StringRef LineFilter,
ClangTidyGlobalOptions &Options);
/// \brief Parses configuration from JSON and returns \c ClangTidyOptions or an
/// error.
llvm::ErrorOr<ClangTidyOptions> parseConfiguration(llvm::StringRef Config);
/// \brief Serializes configuration to a YAML-encoded string.
std::string configurationAsText(const ClangTidyOptions &Options);
} // end namespace tidy
} // end namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H

View File

@@ -11,6 +11,6 @@ CLANG_LEVEL := ../../..
LIBRARYNAME := clangTidy
include $(CLANG_LEVEL)/../../Makefile.config
DIRS = utils readability llvm google misc tool
DIRS = llvm google tool
include $(CLANG_LEVEL)/Makefile

View File

@@ -1,225 +0,0 @@
#!/usr/bin/env python
#
#===- add_new_check.py - clang-tidy check generator ----------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
import os
import re
import sys
# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
# and 'False' if the entry already existed.
def adapt_cmake(module_path, check_name_camel):
filename = os.path.join(module_path, 'CMakeLists.txt')
with open(filename, 'r') as f:
lines = f.read().split('\n')
# .split with separator returns one more element. Ignore it.
lines = lines[:-1]
cpp_file = check_name_camel + '.cpp'
# Figure out whether this check already exists.
for line in lines:
if line.strip() == cpp_file:
return False
with open(filename, 'w') as f:
cpp_found = False
file_added = False
for line in lines:
if not file_added and (line.endswith('.cpp') or cpp_found):
cpp_found = True
if line.strip() > cpp_file:
f.write(' ' + cpp_file + '\n')
file_added = True
f.write(line + '\n')
return True
# Adds a header for the new check.
def write_header(module_path, module, check_name, check_name_camel):
filename = os.path.join(module_path, check_name_camel) + '.h'
with open(filename, 'w') as f:
header_guard = ('LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_' + module.upper() +
'_' + check_name.upper().replace('-', '_') + '_H')
f.write('//===--- ')
f.write(os.path.basename(filename))
f.write(' - clang-tidy')
f.write('-' * max(0, 43 - len(os.path.basename(filename))))
f.write('*- C++ -*-===//')
f.write("""
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef %(header_guard)s
#define %(header_guard)s
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
class %(check_name)s : public ClangTidyCheck {
public:
%(check_name)s(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace tidy
} // namespace clang
#endif // %(header_guard)s
""" % {'header_guard': header_guard,
'check_name': check_name_camel})
# Adds the implementation of the new check.
def write_implementation(module_path, check_name_camel):
filename = os.path.join(module_path, check_name_camel) + '.cpp'
with open(filename, 'w') as f:
f.write('//===--- ')
f.write(os.path.basename(filename))
f.write(' - clang-tidy')
f.write('-' * max(0, 52 - len(os.path.basename(filename))))
f.write('-===//')
f.write("""
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "%(check_name)s.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
void %(check_name)s::registerMatchers(MatchFinder *Finder) {
// FIXME: Add matchers.
Finder->addMatcher(functionDecl().bind("x"), this);
}
void %(check_name)s::check(const MatchFinder::MatchResult &Result) {
// FIXME: Add callback implementation.
const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x");
if (MatchedDecl->getName().startswith("awesome_"))
return;
diag(MatchedDecl->getLocation(), "function '%%0' is insufficiently awesome")
<< MatchedDecl->getName()
<< FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
}
} // namespace tidy
} // namespace clang
""" % {'check_name': check_name_camel})
# Modifies the module to include the new check.
def adapt_module(module_path, module, check_name, check_name_camel):
filename = os.path.join(module_path, module.capitalize() + 'TidyModule.cpp')
with open(filename, 'r') as f:
lines = f.read().split('\n')
# .split with separator returns one more element. Ignore it.
lines = lines[:-1]
with open(filename, 'w') as f:
header_added = False
header_found = False
check_added = False
check_decl = (' CheckFactories.registerCheck<' + check_name_camel +
'>(\n "' + module + '-' + check_name + '");\n')
for line in lines:
if not header_added:
match = re.search('#include "(.*)"', line)
if match:
header_found = True
if match.group(1) > check_name_camel:
header_added = True
f.write('#include "' + check_name_camel + '.h"\n')
elif header_found:
header_added = True
f.write('#include "' + check_name_camel + '.h"\n')
if not check_added:
if line.strip() == '}':
check_added = True
f.write(check_decl)
else:
match = re.search('registerCheck<(.*)>', line)
if match and match.group(1) > check_name_camel:
check_added = True
f.write(check_decl)
f.write(line + '\n')
# Adds a test for the check.
def write_test(module_path, module, check_name):
check_name_dashes = module + '-' + check_name
filename = os.path.join(module_path, '../../test/clang-tidy',
check_name_dashes + '.cpp')
with open(filename, 'w') as f:
f.write(
"""// RUN: $(dirname %%s)/check_clang_tidy.sh %%s %(check_name_dashes)s %%t
// REQUIRES: shell
// FIXME: Add something that triggers the check here.
void f();
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'f' is insufficiently awesome [%(check_name_dashes)s]
// FIXME: Verify the applied fix.
// * Make the CHECK patterns specific enough and try to make verified lines
// unique to avoid incorrect matches.
// * Use {{}} for regular expressions.
// CHECK-FIXES: {{^}}void awesome_f();{{$}}
// FIXME: Add something that doesn't trigger the check here.
void awesome_f2();
""" % {"check_name_dashes" : check_name_dashes})
def main():
if len(sys.argv) != 3:
print 'Usage: add_new_check.py <module> <check>, e.g.\n'
print 'add_new_check.py misc awesome-functions\n'
return
module = sys.argv[1]
check_name = sys.argv[2]
check_name_camel = ''.join(map(lambda elem: elem.capitalize(),
check_name.split('-'))) + 'Check'
clang_tidy_path = os.path.dirname(sys.argv[0])
module_path = os.path.join(clang_tidy_path, module)
if not adapt_cmake(module_path, check_name_camel):
return
write_header(module_path, module, check_name, check_name_camel)
write_implementation(module_path, check_name_camel)
adapt_module(module_path, module, check_name, check_name_camel)
write_test(module_path, module, check_name)
if __name__ == '__main__':
main()

View File

@@ -1,153 +0,0 @@
//===--- AvoidCStyleCastsCheck.cpp - clang-tidy -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AvoidCStyleCastsCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace readability {
void
AvoidCStyleCastsCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
Finder->addMatcher(
cStyleCastExpr(
// Filter out (EnumType)IntegerLiteral construct, which is generated
// for non-type template arguments of enum types.
// FIXME: Remove this once this is fixed in the AST.
unless(hasParent(substNonTypeTemplateParmExpr())),
// Avoid matches in template instantiations.
unless(isInTemplateInstantiation())).bind("cast"),
this);
}
bool needsConstCast(QualType SourceType, QualType DestType) {
SourceType = SourceType.getNonReferenceType();
DestType = DestType.getNonReferenceType();
while (SourceType->isPointerType() && DestType->isPointerType()) {
SourceType = SourceType->getPointeeType();
DestType = DestType->getPointeeType();
if (SourceType.isConstQualified() && !DestType.isConstQualified())
return true;
}
return false;
}
bool pointedTypesAreEqual(QualType SourceType, QualType DestType) {
SourceType = SourceType.getNonReferenceType();
DestType = DestType.getNonReferenceType();
while (SourceType->isPointerType() && DestType->isPointerType()) {
SourceType = SourceType->getPointeeType();
DestType = DestType->getPointeeType();
}
return SourceType.getUnqualifiedType() == DestType.getUnqualifiedType();
}
void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
const auto *CastExpr = Result.Nodes.getNodeAs<CStyleCastExpr>("cast");
auto ParenRange = CharSourceRange::getTokenRange(CastExpr->getLParenLoc(),
CastExpr->getRParenLoc());
// Ignore casts in macros.
if (ParenRange.getBegin().isMacroID() || ParenRange.getEnd().isMacroID())
return;
// Casting to void is an idiomatic way to mute "unused variable" and similar
// warnings.
if (CastExpr->getTypeAsWritten()->isVoidType())
return;
QualType SourceType =
CastExpr->getSubExprAsWritten()->getType().getCanonicalType();
QualType DestType = CastExpr->getTypeAsWritten().getCanonicalType();
if (SourceType == DestType) {
diag(CastExpr->getLocStart(), "Redundant cast to the same type.")
<< FixItHint::CreateRemoval(ParenRange);
return;
}
// The rest of this check is only relevant to C++.
if (!Result.Context->getLangOpts().CPlusPlus)
return;
// Leave type spelling exactly as it was (unlike
// getTypeAsWritten().getAsString() which would spell enum types 'enum X').
StringRef DestTypeString = Lexer::getSourceText(
CharSourceRange::getTokenRange(
CastExpr->getLParenLoc().getLocWithOffset(1),
CastExpr->getRParenLoc().getLocWithOffset(-1)),
*Result.SourceManager, Result.Context->getLangOpts());
auto diag_builder =
diag(CastExpr->getLocStart(), "C-style casts are discouraged. %0");
auto ReplaceWithCast = [&](StringRef CastType) {
diag_builder << ("Use " + CastType + ".").str();
const Expr *SubExpr = CastExpr->getSubExprAsWritten()->IgnoreImpCasts();
std::string CastText = (CastType + "<" + DestTypeString + ">").str();
if (!isa<ParenExpr>(SubExpr)) {
CastText.push_back('(');
diag_builder << FixItHint::CreateInsertion(
Lexer::getLocForEndOfToken(SubExpr->getLocEnd(), 0,
*Result.SourceManager,
Result.Context->getLangOpts()),
")");
}
diag_builder << FixItHint::CreateReplacement(ParenRange, CastText);
};
// Suggest appropriate C++ cast. See [expr.cast] for cast notation semantics.
switch (CastExpr->getCastKind()) {
case CK_NoOp:
if (needsConstCast(SourceType, DestType) &&
pointedTypesAreEqual(SourceType, DestType)) {
ReplaceWithCast("const_cast");
return;
}
if (DestType->isReferenceType() &&
(SourceType.getNonReferenceType() ==
DestType.getNonReferenceType().withConst() ||
SourceType.getNonReferenceType() == DestType.getNonReferenceType())) {
ReplaceWithCast("const_cast");
return;
}
// FALLTHROUGH
case clang::CK_IntegralCast:
// Convert integral and no-op casts between builtin types and enums to
// static_cast. A cast from enum to integer may be unnecessary, but it's
// still retained.
if ((SourceType->isBuiltinType() || SourceType->isEnumeralType()) &&
(DestType->isBuiltinType() || DestType->isEnumeralType())) {
ReplaceWithCast("static_cast");
return;
}
break;
case CK_BitCast:
// FIXME: Suggest const_cast<...>(reinterpret_cast<...>(...)) replacement.
if (!needsConstCast(SourceType, DestType)) {
ReplaceWithCast("reinterpret_cast");
return;
}
break;
default:
break;
}
diag_builder << "Use static_cast/const_cast/reinterpret_cast.";
}
} // namespace readability
} // namespace tidy
} // namespace clang

View File

@@ -1,39 +0,0 @@
//===--- AvoidCStyleCastsCheck.h - clang-tidy -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOID_C_STYLE_CASTS_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOID_C_STYLE_CASTS_CHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace readability {
/// \brief Finds usages of C-style casts.
///
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Casting#Casting
/// Corresponding cpplint.py check name: 'readability/casting'.
///
/// This check is similar to -Wold-style-cast, but it will suggest automated
/// fixes eventually. The reported locations should not be different from the
/// ones generated by -Wold-style-cast.
class AvoidCStyleCastsCheck : public ClangTidyCheck {
public:
AvoidCStyleCastsCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace readability
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOID_C_STYLE_CASTS_CHECK_H

View File

@@ -1,24 +1,11 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyGoogleModule
AvoidCStyleCastsCheck.cpp
ExplicitConstructorCheck.cpp
ExplicitMakePairCheck.cpp
GoogleTidyModule.cpp
IntegerTypesCheck.cpp
MemsetZeroLengthCheck.cpp
NamedParameterCheck.cpp
OverloadedUnaryAndCheck.cpp
StringReferenceMemberCheck.cpp
TodoCommentCheck.cpp
UnnamedNamespaceInHeaderCheck.cpp
UsingNamespaceDirectiveCheck.cpp
LINK_LIBS
clangAST
clangASTMatchers
clangBasic
clangLex
clangTidy
clangTidyReadabilityModule
)
target_link_libraries(clangTidyGoogleModule
clangTidy
clangTooling
clangBasic
clangASTMatchers
)

View File

@@ -1,114 +0,0 @@
//===--- ExplicitConstructorCheck.cpp - clang-tidy ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ExplicitConstructorCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(constructorDecl(unless(isInstantiated())).bind("ctor"),
this);
}
// Looks for the token matching the predicate and returns the range of the found
// token including trailing whitespace.
SourceRange FindToken(const SourceManager &Sources, LangOptions LangOpts,
SourceLocation StartLoc, SourceLocation EndLoc,
bool (*Pred)(const Token &)) {
if (StartLoc.isMacroID() || EndLoc.isMacroID())
return SourceRange();
FileID File = Sources.getFileID(Sources.getSpellingLoc(StartLoc));
StringRef Buf = Sources.getBufferData(File);
const char *StartChar = Sources.getCharacterData(StartLoc);
Lexer Lex(StartLoc, LangOpts, StartChar, StartChar, Buf.end());
Lex.SetCommentRetentionState(true);
Token Tok;
do {
Lex.LexFromRawLexer(Tok);
if (Pred(Tok)) {
Token NextTok;
Lex.LexFromRawLexer(NextTok);
return SourceRange(Tok.getLocation(), NextTok.getLocation());
}
} while (Tok.isNot(tok::eof) && Tok.getLocation() < EndLoc);
return SourceRange();
}
bool isStdInitializerList(QualType Type) {
if (const RecordType *RT = Type.getCanonicalType()->getAs<RecordType>()) {
if (ClassTemplateSpecializationDecl *Specialization =
dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
ClassTemplateDecl *Template = Specialization->getSpecializedTemplate();
// First use the fast getName() method to avoid unnecessary calls to the
// slow getQualifiedNameAsString().
return Template->getName() == "initializer_list" &&
Template->getQualifiedNameAsString() == "std::initializer_list";
}
}
return false;
}
void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
const CXXConstructorDecl *Ctor =
Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
// Do not be confused: isExplicit means 'explicit' keyword is present,
// isImplicit means that it's a compiler-generated constructor.
if (Ctor->isOutOfLine() || Ctor->isImplicit() || Ctor->isDeleted() ||
Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1)
return;
bool takesInitializerList = isStdInitializerList(
Ctor->getParamDecl(0)->getType().getNonReferenceType());
if (Ctor->isExplicit() &&
(Ctor->isCopyOrMoveConstructor() || takesInitializerList)) {
auto isKWExplicit = [](const Token &Tok) {
return Tok.is(tok::raw_identifier) &&
Tok.getRawIdentifier() == "explicit";
};
SourceRange ExplicitTokenRange =
FindToken(*Result.SourceManager, Result.Context->getLangOpts(),
Ctor->getOuterLocStart(), Ctor->getLocEnd(), isKWExplicit);
StringRef ConstructorDescription;
if (Ctor->isMoveConstructor())
ConstructorDescription = "move";
else if (Ctor->isCopyConstructor())
ConstructorDescription = "copy";
else
ConstructorDescription = "initializer-list";
DiagnosticBuilder Diag =
diag(Ctor->getLocation(),
"%0 constructor should not be declared explicit")
<< ConstructorDescription;
if (ExplicitTokenRange.isValid()) {
Diag << FixItHint::CreateRemoval(
CharSourceRange::getCharRange(ExplicitTokenRange));
}
return;
}
if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() ||
takesInitializerList)
return;
SourceLocation Loc = Ctor->getLocation();
diag(Loc, "single-argument constructors must be explicit")
<< FixItHint::CreateInsertion(Loc, "explicit ");
}
} // namespace tidy
} // namespace clang

View File

@@ -1,33 +0,0 @@
//===--- ExplicitConstructorCheck.h - clang-tidy ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_CONSTRUCTOR_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_CONSTRUCTOR_CHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
/// \brief Checks that all single-argument constructors are explicit.
///
/// see:
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Explicit_Constructors
class ExplicitConstructorCheck : public ClangTidyCheck {
public:
ExplicitConstructorCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_CONSTRUCTOR_CHECK_H

View File

@@ -1,71 +0,0 @@
//===--- ExplicitMakePairCheck.cpp - clang-tidy -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ExplicitMakePairCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
using namespace clang::ast_matchers;
namespace clang {
namespace ast_matchers {
AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) {
return Node.hasExplicitTemplateArgs();
}
} // namespace ast_matchers
namespace tidy {
namespace build {
void
ExplicitMakePairCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
// Look for std::make_pair with explicit template args. Ignore calls in
// templates.
Finder->addMatcher(
callExpr(unless(isInTemplateInstantiation()),
callee(expr(ignoringParenImpCasts(
declRefExpr(hasExplicitTemplateArgs(),
to(functionDecl(hasName("::std::make_pair"))))
.bind("declref"))))).bind("call"),
this);
}
void ExplicitMakePairCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>("declref");
// Sanity check: The use might have overriden ::std::make_pair.
if (Call->getNumArgs() != 2)
return;
const Expr *Arg0 = Call->getArg(0)->IgnoreParenImpCasts();
const Expr *Arg1 = Call->getArg(1)->IgnoreParenImpCasts();
// If types don't match, we suggest replacing with std::pair and explicit
// template arguments. Otherwise just remove the template arguments from
// make_pair.
if (Arg0->getType() != Call->getArg(0)->getType() ||
Arg1->getType() != Call->getArg(1)->getType()) {
diag(Call->getLocStart(), "for C++11-compatibility, use pair directly")
<< FixItHint::CreateReplacement(
SourceRange(DeclRef->getLocStart(), DeclRef->getLAngleLoc()),
"std::pair<");
} else {
diag(Call->getLocStart(),
"for C++11-compatibility, omit template arguments from make_pair")
<< FixItHint::CreateRemoval(
SourceRange(DeclRef->getLAngleLoc(), DeclRef->getRAngleLoc()));
}
}
} // namespace build
} // namespace tidy
} // namespace clang

View File

@@ -1,37 +0,0 @@
//===--- ExplicitMakePairCheck.h - clang-tidy -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_MAKE_PAIR_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_MAKE_PAIR_CHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace build {
/// \brief Check that make_pair's template arguments are deduced.
///
/// G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are
/// specified explicitly, and such use isn't intended in any case.
///
/// Corresponding cpplint.py check name: 'build/explicit_make_pair'.
class ExplicitMakePairCheck : public ClangTidyCheck {
public:
ExplicitMakePairCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace build
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_MAKE_PAIR_CHECK_H

View File

@@ -7,74 +7,45 @@
//
//===----------------------------------------------------------------------===//
#include "GoogleTidyModule.h"
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "../readability/BracesAroundStatementsCheck.h"
#include "../readability/FunctionSize.h"
#include "../readability/NamespaceCommentCheck.h"
#include "../readability/RedundantSmartptrGet.h"
#include "AvoidCStyleCastsCheck.h"
#include "ExplicitConstructorCheck.h"
#include "ExplicitMakePairCheck.h"
#include "IntegerTypesCheck.h"
#include "MemsetZeroLengthCheck.h"
#include "NamedParameterCheck.h"
#include "OverloadedUnaryAndCheck.h"
#include "StringReferenceMemberCheck.h"
#include "TodoCommentCheck.h"
#include "UnnamedNamespaceInHeaderCheck.h"
#include "UsingNamespaceDirectiveCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PPCallbacks.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
void
ExplicitConstructorCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
Finder->addMatcher(constructorDecl().bind("construct"), this);
}
void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
const CXXConstructorDecl *Ctor =
Result.Nodes.getNodeAs<CXXConstructorDecl>("construct");
if (!Ctor->isExplicit() && !Ctor->isImplicit() && Ctor->getNumParams() >= 1 &&
Ctor->getMinRequiredArguments() <= 1) {
SourceLocation Loc = Ctor->getLocation();
Context->Diag(Loc, "Single-argument constructors must be explicit")
<< FixItHint::CreateInsertion(Loc, "explicit ");
}
}
class GoogleModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.registerCheck<build::ExplicitMakePairCheck>(
"google-build-explicit-make-pair");
CheckFactories.registerCheck<build::UnnamedNamespaceInHeaderCheck>(
"google-build-namespaces");
CheckFactories.registerCheck<build::UsingNamespaceDirectiveCheck>(
"google-build-using-namespace");
CheckFactories.registerCheck<ExplicitConstructorCheck>(
"google-explicit-constructor");
CheckFactories.registerCheck<runtime::IntegerTypesCheck>(
"google-runtime-int");
CheckFactories.registerCheck<runtime::OverloadedUnaryAndCheck>(
"google-runtime-operator");
CheckFactories.registerCheck<runtime::StringReferenceMemberCheck>(
"google-runtime-member-string-references");
CheckFactories.registerCheck<runtime::MemsetZeroLengthCheck>(
"google-runtime-memset");
CheckFactories.registerCheck<readability::AvoidCStyleCastsCheck>(
"google-readability-casting");
CheckFactories.registerCheck<readability::NamedParameterCheck>(
"google-readability-function");
CheckFactories.registerCheck<readability::TodoCommentCheck>(
"google-readability-todo");
CheckFactories.registerCheck<readability::BracesAroundStatementsCheck>(
"google-readability-braces-around-statements");
CheckFactories.registerCheck<readability::FunctionSizeCheck>(
"google-readability-function-size");
CheckFactories.registerCheck<readability::NamespaceCommentCheck>(
"google-readability-namespace-comments");
CheckFactories.registerCheck<readability::RedundantSmartptrGet>(
"google-readability-redundant-smartptr-get");
}
ClangTidyOptions getModuleOptions() override {
ClangTidyOptions Options;
auto &Opts = Options.CheckOptions;
Opts["google-readability-braces-around-statements.ShortStatementLines"] =
"1";
Opts["google-readability-function-size.StatementThreshold"] = "800";
Opts["google-readability-namespace-comments.ShortNamespaceLines"] = "10";
Opts["google-readability-namespace-comments.SpacesBeforeComments"] = "2";
return Options;
virtual void addCheckFactories(ClangTidyCheckFactories &CheckFactories) {
CheckFactories.addCheckFactory(
"google-explicit-constructor",
new ClangTidyCheckFactory<ExplicitConstructorCheck>());
}
};

View File

@@ -0,0 +1,31 @@
//===--- GoogleTidyModule.h - clang-tidy ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
/// \brief Checks that all single-argument constructors are explicit.
///
/// see:
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Explicit_Constructors
class ExplicitConstructorCheck : public ClangTidyCheck {
public:
virtual void registerMatchers(ast_matchers::MatchFinder *Finder);
virtual void check(const ast_matchers::MatchFinder::MatchResult &Result);
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H

View File

@@ -1,102 +0,0 @@
//===--- IntegerTypesCheck.cpp - clang-tidy -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "IntegerTypesCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/TargetInfo.h"
namespace clang {
namespace tidy {
namespace runtime {
using namespace ast_matchers;
void IntegerTypesCheck::registerMatchers(MatchFinder *Finder) {
// Find all TypeLocs.
Finder->addMatcher(typeLoc().bind("tl"), this);
}
void IntegerTypesCheck::check(const MatchFinder::MatchResult &Result) {
// The relevant Style Guide rule only applies to C++.
if (!Result.Context->getLangOpts().CPlusPlus)
return;
auto TL = *Result.Nodes.getNodeAs<TypeLoc>("tl");
SourceLocation Loc = TL.getLocStart();
if (Loc.isInvalid() || Loc.isMacroID())
return;
// Look through qualification.
if (auto QualLoc = TL.getAs<QualifiedTypeLoc>())
TL = QualLoc.getUnqualifiedLoc();
auto BuiltinLoc = TL.getAs<BuiltinTypeLoc>();
if (!BuiltinLoc)
return;
bool IsSigned;
unsigned Width;
const TargetInfo &TargetInfo = Result.Context->getTargetInfo();
// Look for uses of short, long, long long and their unsigned versions.
switch (BuiltinLoc.getTypePtr()->getKind()) {
case BuiltinType::Short:
Width = TargetInfo.getShortWidth();
IsSigned = true;
break;
case BuiltinType::Long:
Width = TargetInfo.getLongWidth();
IsSigned = true;
break;
case BuiltinType::LongLong:
Width = TargetInfo.getLongLongWidth();
IsSigned = true;
break;
case BuiltinType::UShort:
Width = TargetInfo.getShortWidth();
IsSigned = false;
break;
case BuiltinType::ULong:
Width = TargetInfo.getLongWidth();
IsSigned = false;
break;
case BuiltinType::ULongLong:
Width = TargetInfo.getLongLongWidth();
IsSigned = false;
break;
default:
return;
}
// We allow "unsigned short port" as that's reasonably common and required by
// the sockets API.
const StringRef Port = "unsigned short port";
const char *Data = Result.SourceManager->getCharacterData(Loc);
if (!std::strncmp(Data, Port.data(), Port.size()) &&
!isIdentifierBody(Data[Port.size()]))
return;
std::string Replacement =
((IsSigned ? SignedTypePrefix : UnsignedTypePrefix) + Twine(Width) +
(AddUnderscoreT ? "_t" : "")).str();
// We don't add a fix-it as changing the type can easily break code,
// e.g. when a function requires a 'long' argument on all platforms.
// QualTypes are printed with implicit quotes.
diag(Loc, "consider replacing %0 with '%1'") << BuiltinLoc.getType()
<< Replacement;
}
} // namespace runtime
} // namespace tidy
} // namespace clang

View File

@@ -1,40 +0,0 @@
//===--- IntegerTypesCheck.h - clang-tidy -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_INTEGERTYPESCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_INTEGERTYPESCHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace runtime {
/// \brief Finds uses of short, long and long long and suggest replacing them
/// with u?intXX(_t)?.
/// Correspondig cpplint.py check: runtime/int.
class IntegerTypesCheck : public ClangTidyCheck {
public:
IntegerTypesCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context), UnsignedTypePrefix("uint"),
SignedTypePrefix("int"), AddUnderscoreT(false) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const StringRef UnsignedTypePrefix;
const StringRef SignedTypePrefix;
const bool AddUnderscoreT;
};
} // namespace runtime
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_INTEGERTYPESCHECK_H

View File

@@ -1,89 +0,0 @@
//===--- MemsetZeroLengthCheck.cpp - clang-tidy -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MemsetZeroLengthCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace runtime {
void
MemsetZeroLengthCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
// Look for memset(x, y, 0) as those is most likely an argument swap.
// TODO: Also handle other standard functions that suffer from the same
// problem, e.g. memchr.
Finder->addMatcher(
callExpr(callee(functionDecl(hasName("::memset"))), argumentCountIs(3),
unless(isInTemplateInstantiation())).bind("decl"),
this);
}
/// \brief Get a StringRef representing a SourceRange.
static StringRef getAsString(const MatchFinder::MatchResult &Result,
SourceRange R) {
const SourceManager &SM = *Result.SourceManager;
// Don't even try to resolve macro or include contraptions. Not worth emitting
// a fixit for.
if (R.getBegin().isMacroID() ||
!SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
return StringRef();
const char *Begin = SM.getCharacterData(R.getBegin());
const char *End = SM.getCharacterData(Lexer::getLocForEndOfToken(
R.getEnd(), 0, SM, Result.Context->getLangOpts()));
return StringRef(Begin, End - Begin);
}
void MemsetZeroLengthCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("decl");
const Expr *Arg1 = Call->getArg(1);
const Expr *Arg2 = Call->getArg(2);
// Try to evaluate the second argument so we can also find values that are not
// just literals.
llvm::APSInt Value1, Value2;
if (Arg2->isValueDependent() ||
!Arg2->EvaluateAsInt(Value2, *Result.Context) || Value2 != 0)
return;
// If both arguments evaluate to zero emit a warning without fix suggestions.
if (!Arg1->isValueDependent() &&
Arg1->EvaluateAsInt(Value1, *Result.Context) &&
(Value1 == 0 || Value1.isNegative())) {
diag(Call->getLocStart(), "memset of size zero");
return;
}
// Emit a warning and fix-its to swap the arguments.
auto D = diag(Call->getLocStart(),
"memset of size zero, potentially swapped arguments");
SourceRange LHSRange = Arg1->getSourceRange();
SourceRange RHSRange = Arg2->getSourceRange();
StringRef RHSString = getAsString(Result, RHSRange);
StringRef LHSString = getAsString(Result, LHSRange);
if (LHSString.empty() || RHSString.empty())
return;
D << FixItHint::CreateReplacement(CharSourceRange::getTokenRange(LHSRange),
RHSString)
<< FixItHint::CreateReplacement(CharSourceRange::getTokenRange(RHSRange),
LHSString);
}
} // namespace runtime
} // namespace tidy
} // namespace clang

View File

@@ -1,37 +0,0 @@
//===--- MemsetZeroLengthCheck.h - clang-tidy ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_MEMSET_ZERO_LENGTH_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_MEMSET_ZERO_LENGTH_CHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace runtime {
/// \brief Finds calls to memset with a literal zero in the length argument.
///
/// This is most likely unintended and the length and value arguments are
/// swapped.
///
/// Corresponding cpplint.py check name: 'runtime/memset'.
class MemsetZeroLengthCheck : public ClangTidyCheck {
public:
MemsetZeroLengthCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace runtime
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_MEMSET_ZERO_LENGTH_CHECK_H

View File

@@ -1,125 +0,0 @@
//===--- NamedParameterCheck.cpp - clang-tidy -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "NamedParameterCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace readability {
void NamedParameterCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
Finder->addMatcher(functionDecl(unless(isInstantiated())).bind("decl"), this);
}
void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) {
const SourceManager &SM = *Result.SourceManager;
const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>("decl");
SmallVector<std::pair<const FunctionDecl *, unsigned>, 4> UnnamedParams;
// Ignore implicitly generated members.
if (Function->isImplicit())
return;
// Ignore declarations without a definition if we're not dealing with an
// overriden method.
const FunctionDecl *Definition = nullptr;
if ((!Function->isDefined(Definition) || Function->isDefaulted() ||
Function->isDeleted()) &&
(!isa<CXXMethodDecl>(Function) ||
cast<CXXMethodDecl>(Function)->size_overridden_methods() == 0))
return;
// TODO: Handle overloads.
// TODO: We could check that all redeclarations use the same name for
// arguments in the same position.
for (unsigned I = 0, E = Function->getNumParams(); I != E; ++I) {
const ParmVarDecl *Parm = Function->getParamDecl(I);
// Look for unnamed parameters.
if (!Parm->getName().empty())
continue;
// Don't warn on the dummy argument on post-inc and post-dec operators.
if ((Function->getOverloadedOperator() == OO_PlusPlus ||
Function->getOverloadedOperator() == OO_MinusMinus) &&
Parm->getType()->isSpecificBuiltinType(BuiltinType::Int))
continue;
// Sanity check the source locations.
if (!Parm->getLocation().isValid() || Parm->getLocation().isMacroID() ||
!SM.isWrittenInSameFile(Parm->getLocStart(), Parm->getLocation()))
continue;
// Skip gmock testing::Unused parameters.
if (auto Typedef = Parm->getType()->getAs<clang::TypedefType>())
if (Typedef->getDecl()->getQualifiedNameAsString() == "testing::Unused")
continue;
// Skip std::nullptr_t.
if (Parm->getType().getCanonicalType()->isNullPtrType())
continue;
// Look for comments. We explicitly want to allow idioms like
// void foo(int /*unused*/)
const char *Begin = SM.getCharacterData(Parm->getLocStart());
const char *End = SM.getCharacterData(Parm->getLocation());
StringRef Data(Begin, End - Begin);
if (Data.find("/*") != StringRef::npos)
continue;
UnnamedParams.push_back(std::make_pair(Function, I));
}
// Emit only one warning per function but fixits for all unnamed parameters.
if (!UnnamedParams.empty()) {
const ParmVarDecl *FirstParm =
UnnamedParams.front().first->getParamDecl(UnnamedParams.front().second);
auto D = diag(FirstParm->getLocation(),
"all parameters should be named in a function");
for (auto P : UnnamedParams) {
// Fallback to an unused marker.
StringRef NewName = "unused";
// If the method is overridden, try to copy the name from the base method
// into the overrider.
const auto *M = dyn_cast<CXXMethodDecl>(P.first);
if (M && M->size_overridden_methods() > 0) {
const ParmVarDecl *OtherParm =
(*M->begin_overridden_methods())->getParamDecl(P.second);
StringRef Name = OtherParm->getName();
if (!Name.empty())
NewName = Name;
}
// If the definition has a named parameter use that name.
if (Definition) {
const ParmVarDecl *DefParm = Definition->getParamDecl(P.second);
StringRef Name = DefParm->getName();
if (!Name.empty())
NewName = Name;
}
// Now insert the comment. Note that getLocation() points to the place
// where the name would be, this allows us to also get complex cases like
// function pointers right.
const ParmVarDecl *Parm = P.first->getParamDecl(P.second);
D << FixItHint::CreateInsertion(Parm->getLocation(),
" /*" + NewName.str() + "*/");
}
}
}
} // namespace readability
} // namespace tidy
} // namespace clang

View File

@@ -1,35 +0,0 @@
//===--- NamedParameterCheck.h - clang-tidy ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_NAMED_PARAMETER_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_NAMED_PARAMETER_CHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace readability {
/// \brief Find functions with unnamed arguments.
///
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Function_Declarations_and_Definitions#Function_Declarations_and_Definitions
/// Corresponding cpplint.py check name: 'readability/function'.
class NamedParameterCheck : public ClangTidyCheck {
public:
NamedParameterCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace readability
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_NAMED_PARAMETER_CHECK_H

Some files were not shown because too many files have changed in this diff Show More