Sort the elements of Sema::OpenCLTypeExtMap and Sema::OpenCLDeclExtMap
by TypeIDs and DeclIDs to guarantee a stable serialization order.
Differential Revision: https://reviews.llvm.org/D60835
Reviewed By: Anastasia
Reviewers: Anastasia, lebedev.ri
llvm-svn: 358674
This change adds hierarchical "time trace" profiling blocks that can be visualized in Chrome, in a "flame chart" style. Each profiling block can have a "detail" string that for example indicates the file being processed, template name being instantiated, function being optimized etc.
This is taken from GitHub PR: https://github.com/aras-p/llvm-project-20170507/pull/2
Patch by Aras Pranckevičius.
Differential Revision: https://reviews.llvm.org/D58675
llvm-svn: 357340
allocators.
It is better to deduce omp_allocator_handle_t type from the predefined
allocators, because omp.h header might not define it explicitly. Plus,
it allows to identify the predefined allocators correctly when trying to
build the allcoator for the global variables.
llvm-svn: 356607
Summary:
https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf, page 3:
```
structured block
For C/C++, an executable statement, possibly compound, with a single entry at the
top and a single exit at the bottom, or an OpenMP construct.
COMMENT: See Section 2.1 on page 38 for restrictions on structured
blocks.
```
```
2.1 Directive Format
Some executable directives include a structured block. A structured block:
• may contain infinite loops where the point of exit is never reached;
• may halt due to an IEEE exception;
• may contain calls to exit(), _Exit(), quick_exit(), abort() or functions with a
_Noreturn specifier (in C) or a noreturn attribute (in C/C++);
• may be an expression statement, iteration statement, selection statement, or try block, provided
that the corresponding compound statement obtained by enclosing it in { and } would be a
structured block; and
Restrictions
Restrictions to structured blocks are as follows:
• Entry to a structured block must not be the result of a branch.
• The point of exit cannot be a branch out of the structured block.
C / C++
• The point of entry to a structured block must not be a call to setjmp().
• longjmp() and throw() must not violate the entry/exit criteria.
```
Of particular note here is the fact that OpenMP structured blocks are as-if `noexcept`,
in the same sense as with the normal `noexcept` functions in C++.
I.e. if throw happens, and it attempts to travel out of the `noexcept` function
(here: out of the current structured-block), then the program terminates.
Now, one of course can say that since it is explicitly prohibited by the Specification,
then any and all programs that violate this Specification contain undefined behavior,
and are unspecified, and thus no one should care about them. Just don't write broken code /s
But i'm not sure this is a reasonable approach.
I have personally had oss-fuzz issues of this origin - exception thrown inside
of an OpenMP structured-block that is not caught, thus causing program termination.
This issue isn't all that hard to catch, it's not any particularly different from
diagnosing the same situation with the normal `noexcept` function.
Now, clang static analyzer does not presently model exceptions.
But clang-tidy has a simplisic [[ https://clang.llvm.org/extra/clang-tidy/checks/bugprone-exception-escape.html | bugprone-exception-escape ]] check,
and it is even refactored as a `ExceptionAnalyzer` class for reuse.
So it would be trivial to use that analyzer to check for
exceptions escaping out of OpenMP structured blocks. (D59466)
All that sounds too great to be true. Indeed, there is a caveat.
Presently, it's practically impossible to do. To check a OpenMP structured block
you need to somehow 'get' the OpenMP structured block, and you can't because
it's simply not modelled in AST. `CapturedStmt`/`CapturedDecl` is not it's representation.
Now, it is of course possible to write e.g. some AST matcher that would e.g.
match every OpenMP executable directive, and then return the whatever `Stmt` is
the structured block of said executable directive, if any.
But i said //practically//. This isn't practical for the following reasons:
1. This **will** bitrot. That matcher will need to be kept up-to-date,
and refreshed with every new OpenMP spec version.
2. Every single piece of code that would want that knowledge would need to
have such matcher. Well, okay, if it is an AST matcher, it could be shared.
But then you still have `RecursiveASTVisitor` and friends.
`2 > 1`, so now you have code duplication.
So it would be reasonable (and is fully within clang AST spirit) to not
force every single consumer to do that work, but instead store that knowledge
in the correct, and appropriate place - AST, class structure.
Now, there is another hoop we need to get through.
It isn't fully obvious //how// to model this.
The best solution would of course be to simply add a `OMPStructuredBlock` transparent
node. It would be optimal, it would give us two properties:
* Given this `OMPExecutableDirective`, what's it OpenMP structured block?
* It is trivial to check whether the `Stmt*` is a OpenMP structured block (`isa<OMPStructuredBlock>(ptr)`)
But OpenMP structured block isn't **necessarily** the first, direct child of `OMP*Directive`.
(even ignoring the clang's `CapturedStmt`/`CapturedDecl` that were inserted inbetween).
So i'm not sure whether or not we could re-create AST statements after they were already created?
There would be other costs to a new AST node: https://bugs.llvm.org/show_bug.cgi?id=40563#c12
```
1. You will need to break the representation of loops. The body should be replaced by the "structured block" entity.
2. You will need to support serialization/deserialization.
3. You will need to support template instantiation.
4. You will need to support codegen and take this new construct to account in each OpenMP directive.
```
Instead, there **is** an functionally-equivalent, alternative solution, consisting of two parts.
Part 1:
* Add a member function `isStandaloneDirective()` to the `OMPExecutableDirective` class,
that will tell whether this directive is stand-alone or not, as per the spec.
We need it because we can't just check for the existance of associated statements,
see code comment.
* Add a member function `getStructuredBlock()` to the OMPExecutableDirective` class itself,
that assert that this is not a stand-alone directive, and either return the correct loop body
if this is a loop-like directive, or the captured statement.
This way, given an `OMPExecutableDirective`, we can get it's structured block.
Also, since the knowledge is ingrained into the clang OpenMP implementation,
it will not cause any duplication, and //hopefully// won't bitrot.
Great we achieved 1 of 2 properties of `OMPStructuredBlock` approach.
Thus, there is a second part needed:
* How can we check whether a given `Stmt*` is `OMPStructuredBlock`?
Well, we can't really, in general. I can see this workaround:
```
class FunctionASTVisitor : public RecursiveASTVisitor<FunctionASTVisitor> {
using Base = RecursiveASTVisitor<FunctionASTVisitor>;
public:
bool VisitOMPExecDir(OMPExecDir *D) {
OmpStructuredStmts.emplace_back(D.getStructuredStmt());
}
bool VisitSOMETHINGELSE(???) {
if(InOmpStructuredStmt)
HI!
}
bool TraverseStmt(Stmt *Node) {
if (!Node)
return Base::TraverseStmt(Node);
if (OmpStructuredStmts.back() == Node)
++InOmpStructuredStmt;
Base::TraverseStmt(Node);
if (OmpStructuredStmts.back() == Node) {
OmpStructuredStmts.pop_back();
--InOmpStructuredStmt;
}
return true;
}
std::vector<Stmt*> OmpStructuredStmts;
int InOmpStructuredStmt = 0;
};
```
But i really don't see using it in practice.
It's just too intrusive; and again, requires knowledge duplication.
.. but no. The solution lies right on the ground.
Why don't we simply store this `i'm a openmp structured block` in the bitfield of the `Stmt` itself?
This does not appear to have any impact on the memory footprint of the clang AST,
since it's just a single extra bit in the bitfield. At least the static assertions don't fail.
Thus, indeed, we can achieve both of the properties without a new AST node.
We can cheaply set that bit right in sema, at the end of `Sema::ActOnOpenMPExecutableDirective()`,
by just calling the `getStructuredBlock()` that we just added.
Test coverage that demonstrates all this has been added.
This isn't as great with serialization though. Most of it does not use abbrevs,
so we do end up paying the full price (4 bytes?) instead of a single bit.
That price, of course, can be reclaimed by using abbrevs.
In fact, i suspect that //might// not just reclaim these bytes, but pack these PCH significantly.
I'm not seeing a third solution. If there is one, it would be interesting to hear about it.
("just don't write code that would require `isa<OMPStructuredBlock>(ptr)`" is not a solution.)
Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=40563 | PR40563 ]].
Reviewers: ABataev, rjmccall, hfinkel, rsmith, riccibruno, gribozavr
Reviewed By: ABataev, gribozavr
Subscribers: mgorny, aaron.ballman, steveire, guansong, jfb, jdoerfert, cfe-commits
Tags: #clang, #openmp
Differential Revision: https://reviews.llvm.org/D59214
llvm-svn: 356570
Summary:
These ObjC AST classes inherit from Stmt, but don't call `VisitStmt(S);`.
Some were founded with help of existing tests (with `NumStmtFields` bumped to `1`),
but some of them don't even have PCH test coverage. :/
Reviewers: arphaman, sammccall, smeenai, aprantl, rsmith, jordan_rose
Reviewed By: jordan_rose
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59197
llvm-svn: 355987
Add an option to cache the generated PCH in the ModuleCache when
emitting it. This protects clients that build PCHs and read them in the
same process, allowing them to avoid race conditions between parallel
jobs the same way that Clang's implicit module build system does.
rdar://problem/48740787
llvm-svn: 355950
Leverage the InMemoryModuleCache to invalidate a module the first time
it fails to import (and to lock a module as soon as it's built or
imported successfully). For implicit module builds, this optimizes
importing deep graphs where the leaf module is out-of-date; see example
near the end of the commit message.
Previously the cache finalized ("locked in") all modules imported so far
when starting a new module build. This was sufficient to prevent
loading two versions of the same module, but was somewhat arbitrary and
hard to reason about.
Now the cache explicitly tracks module state, where each module must be
one of:
- Unknown: module not in the cache (yet).
- Tentative: module in the cache, but not yet fully imported.
- ToBuild: module found on disk could not be imported; need to build.
- Final: module in the cache has been successfully built or imported.
Preventing repeated failed imports avoids variation in builds based on
shifting filesystem state. Now it's guaranteed that a module is loaded
from disk exactly once. It now seems safe to remove
FileManager::invalidateCache, but I'm leaving that for a later commit.
The new, precise logic uncovered a pre-existing problem in the cache:
the map key is the module filename, and different contexts use different
filenames for the same PCM file. (In particular, the test
Modules/relative-import-path.c does not build without this commit.
r223577 started using a relative path to describe a module's base
directory when importing it within another module. As a result, the
module cache sees an absolute path when (a) building the module or
importing it at the top-level, and a relative path when (b) importing
the module underneath another one.)
The "obvious" fix is to resolve paths using FileManager::getVirtualFile
and change the map key for the cache to a FileEntry, but some contexts
(particularly related to ASTUnit) have a shorter lifetime for their
FileManager than the InMemoryModuleCache. This is worth pursuing
further in a later commit; perhaps by tying together the FileManager and
InMemoryModuleCache lifetime, or moving the in-memory PCM storage into a
VFS layer.
For now, use the PCM's base directory as-written for constructing the
filename to check the ModuleCache.
Example
=======
To understand the build optimization, first consider the build of a
module graph TU -> A -> B -> C -> D with an empty cache:
TU builds A'
A' builds B'
B' builds C'
C' builds D'
imports D'
B' imports C'
imports D'
A' imports B'
imports C'
imports D'
TU imports A'
imports B'
imports C'
imports D'
If we build TU again, where A, B, C, and D are in the cache and D is
out-of-date, we would previously get this build:
TU imports A
imports B
imports C
imports D (out-of-date)
TU builds A'
A' imports B
imports C
imports D (out-of-date)
builds B'
B' imports C
imports D (out-of-date)
builds C'
C' imports D (out-of-date)
builds D'
imports D'
B' imports C'
imports D'
A' imports B'
imports C'
imports D'
TU imports A'
imports B'
imports C'
imports D'
After this commit, we'll immediateley invalidate A, B, C, and D when we
first observe that D is out-of-date, giving this build:
TU imports A
imports B
imports C
imports D (out-of-date)
TU builds A' // The same graph as an empty cache.
A' builds B'
B' builds C'
C' builds D'
imports D'
B' imports C'
imports D'
A' imports B'
imports C'
imports D'
TU imports A'
imports B'
imports C'
imports D'
The new build matches what we'd naively expect, pretty closely matching
the original build with the empty cache.
rdar://problem/48545366
llvm-svn: 355778
Change MemoryBufferCache to InMemoryModuleCache, moving it from Basic to
Serialization. Another patch will start using it to manage module build
more explicitly, but this is split out because it's mostly mechanical.
Because of the move to Serialization we can no longer abuse the
Preprocessor to forward it to the ASTReader. Besides the rename and
file move, that means Preprocessor::Preprocessor has one fewer parameter
and ASTReader::ASTReader has one more.
llvm-svn: 355777
Add a remark for importing modules. Depending on whether this is a
direct import (into the TU being built by this compiler instance) or
transitive import (into an already-imported module), the diagnostic has
two forms:
importing module 'Foo' from 'path/to/Foo.pcm'
importing module 'Foo' into 'Bar' from 'path/to/Foo.pcm'
Also drop a redundant FileCheck invocation in Rmodule-build.m that was
using -Reverything, since the notes from -Rmodule-import were confusing
it.
https://reviews.llvm.org/D58891
llvm-svn: 355477
initializes a local auto variable or is assigned to a local auto
variable that is declared in the scope that introduced the block
literal.
rdar://problem/13289333
https://reviews.llvm.org/D58514
llvm-svn: 355012
This patch implements the parsing and sema support for the OpenMP
'from'-clause with potential user-defined mappers attached.
User-defined mappers are a new feature in OpenMP 5.0. A 'from'-clause
can have an explicit or implicit associated mapper, which instructs the
compiler to generate and use customized mapping functions. An example is
shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(id: struct S s) map(s, s.d[0:s.len])
struct S ss;
#pragma omp target update from(mapper(id): ss) // use the mapper with name 'id' to map ss from device
Contributed-by: Lingda Li <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D58638
llvm-svn: 354817
This patch implements the parsing and sema support for OpenMP to clause
with potential user-defined mappers attached. User defined mapper is a
new feature in OpenMP 5.0. A to/from clause can have an explicit or
implicit associated mapper, which instructs the compiler to generate and
use customized mapping functions. An example is shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(id: struct S s) map(s, s.d[0:s.len])
struct S ss;
#pragma omp target update to(mapper(id): ss) // use the mapper with name 'id' to map ss to device
Contributed-by: <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D58523
llvm-svn: 354698
This patch implements the parsing and sema support for OpenMP map
clauses with potential user-defined mapper attached. User defined mapper
is a new feature in OpenMP 5.0. A map clause can have an explicit or
implicit associated mapper, which instructs the compiler to generate
extra data mapping. An example is shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(id: struct S s) map(s, s.d[0:s.len])
struct S ss;
#pragma omp target map(mapper(id) tofrom: ss) // use the mapper with name 'id' to map ss
Contributed-by: Lingda Li <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D58074
llvm-svn: 354347
For global variables with unordered initialization that are instantiated
within a module, we previously did not emit the global (or its
initializer) at all unless it was used in the importing translation unit
(and sometimes not even then!), leading to misbehavior and link errors.
We now emit the initializer for an instantiated global variable with
unordered initialization with side-effects in a module into every
translation unit that imports the module. This is unfortunate, but
mostly matches the behavior of a non-modular compilation and seems to be
the best that we can reasonably do.
llvm-svn: 353240
This patch implements parsing and sema for "omp declare mapper"
directive. User defined mapper, i.e., declare mapper directive, is a new
feature in OpenMP 5.0. It is introduced to extend existing map clauses
for the purpose of simplifying the copy of complex data structures
between host and device (i.e., deep copy). An example is shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(struct S s) map(s, s.d[0:s.len]) // Memory region that d points to is also mapped using this mapper.
Contributed-by: Lingda Li <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D56326
llvm-svn: 352906
Store the controlling expression, the association expressions and the
corresponding TypeSourceInfos as trailing objects.
Additionally use the bit-fields of Stmt to store one SourceLocation,
saving one additional pointer. This saves 3 pointers in total per
GenericSelectionExpr.
Differential Revision: https://reviews.llvm.org/D57104
Reviewed By: aaron.ballman
Reviewers: aaron.ballman, steveire
llvm-svn: 352276
Various cleanups to GenericSelectionExpr factored out of D57104. In particular:
1. Move the friend declaration to the top.
2. Introduce a constant ResultDependentIndex instead of the magic "-1".
3. clang-format
4. Group the member function together so that they can be removed as one block
by D57106.
NFC.
Differential Revision: https://reviews.llvm.org/D57238
Reviewed By: aaron.ballman
llvm-svn: 352275
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
Use the newly available space in the bit-fields of Stmt to pack
OverloadExpr, UnresolvedLookupExpr and UnresolvedMemberExpr.
Additionally store the results in the overload set in a trailing array.
This saves 1 pointer + 8 bytes per UnresolvedLookupExpr and
UnresolvedMemberExpr.
Differential Revision: https://reviews.llvm.org/D56368
Reviewed By: rjmccall
llvm-svn: 350732
Use the newly available space in the bit-fields of Stmt.
This saves one pointer per CXXNoexceptExpr/SubstNonTypeTemplateParmExpr.
Use this opportunity to run clang-format on these two classes and
fix some style issues. NFC overall.
llvm-svn: 350627
Use the newly available space in the bit-fields of Stmt. Additionally store
FirstQualifierFoundInScope as a trailing object since it is most of the time
null (non-null for 2 of the 35446 CXXDependentScopeMemberExpr when parsing
all of Boost).
It would be possible to move the data for the nested-name-specifier to a
trailing object too to save another 2 pointers, however doing so did actually
regress the time taken to parse all of Boost slightly.
This saves 8 bytes + 1 pointer per CXXDependentScopeMemberExpr in the vast
majority of cases.
Differential Revision: https://reviews.llvm.org/D56367
Reviewed By: rjmccall
llvm-svn: 350625
Store the optional array size expression, optional initialization expression
and optional placement new arguments in a trailing array. Additionally store
the range for the parenthesized type-id in a trailing object if needed since
in the vast majority of cases the type is not parenthesized (not a single new
expression in the translation unit of SemaDecl.cpp has a parenthesized type-id).
This saves 2 pointers per CXXNewExpr in all cases, and 2 pointers + 8 bytes
per CXXNewExpr in the common case where the type is not parenthesized.
Differential Revision: https://reviews.llvm.org/D56134
Reviewed By: rjmccall
llvm-svn: 350527
Use the newly available space in the bit-fields of Stmt.
This saves 1 pointer per DependentScopeDeclRefExpr/CXXUnresolvedConstructExpr.
Additionally rename "TypeSourceInfo *Type;" to "TypeSourceInfo *TSI;"
as was done in D56022 (r350003) (but this is an internal detail anyway),
and clang-format both classes. NFC.
llvm-svn: 350525
This attribute, called "objc_externally_retained", exposes clang's
notion of pseudo-__strong variables in ARC. Pseudo-strong variables
"borrow" their initializer, meaning that they don't retain/release
it, instead assuming that someone else is keeping their value alive.
If a function is annotated with this attribute, implicitly strong
parameters of that function aren't implicitly retained/released in
the function body, and are implicitly const. This is useful to expose
for performance reasons, most functions don't need the extra safety
of the retain/release, so programmers can opt out as needed.
This attribute can also apply to declarations of local variables,
with similar effect.
Differential revision: https://reviews.llvm.org/D55865
llvm-svn: 350422
Store the arguments of CXXConstructExpr in a trailing array. This is very
similar to the CallExpr case in D55771, with the exception that there is
only one derived class (CXXTemporaryObjectExpr) and that we compute the
offset to the trailing array instead of storing it.
This saves one pointer per CXXConstructExpr and CXXTemporaryObjectExpr.
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D56022
llvm-svn: 350003
Since CallExpr::setNumArgs has been removed, it is now possible to store the
callee expression and the argument expressions of CallExpr in a trailing array.
This saves one pointer per CallExpr, CXXOperatorCallExpr, CXXMemberCallExpr,
CUDAKernelCallExpr and UserDefinedLiteral.
Given that CallExpr is used as a base of the above classes we cannot use
llvm::TrailingObjects. Instead we store the offset in bytes from the this pointer
to the start of the trailing objects and manually do the casts + arithmetic.
Some notes:
1.) I did not try to fit the number of arguments in the bit-fields of Stmt.
This leaves some space for future additions and avoid the discussion about
whether x bits are sufficient to hold the number of arguments.
2.) It would be perfectly possible to recompute the offset to the trailing
objects before accessing the trailing objects. However the trailing objects
are frequently accessed and benchmarks show that it is slightly faster to
just load the offset from the bit-fields. Additionally, because of 1),
we have plenty of space in the bit-fields of Stmt.
Differential Revision: https://reviews.llvm.org/D55771
Reviewed By: rjmccall
llvm-svn: 349910
A map clause with the close map-type-modifier is a hint to
prefer that the variables are mapped using a copy into faster
memory.
Patch by Ahsan Saghir (saghir)
Differential Revision: https://reviews.llvm.org/D55719
llvm-svn: 349551
Move some diagnostics around between Diagnostic*Kinds.td files. Diagnostics
used in multiple places were moved to DiagnosticCommonKinds.td. Diagnostics
listed in the wrong place (ie, Sema diagnostics listed in
DiagnosticsParseKinds.td) were moved to the correct places. One diagnostic
split into two so that the diagnostic string is in the .td file instead of in
code. Cleaned up the diagnostic includes after all the changes.
llvm-svn: 349125
Address spaces are cast into generic before invoking the constructor.
Added support for a trailing Qualifiers object in FunctionProtoType.
Note: This recommits the previously reverted patch,
but now it is commited together with a fix for lldb.
Differential Revision: https://reviews.llvm.org/D54862
llvm-svn: 349019
Summary:
Currently the Clang AST doesn't store information about how the callee of a CallExpr was found. Specifically if it was found using ADL.
However, this information is invaluable to tooling. Consider a tool which renames usages of a function. If the originally CallExpr was formed using ADL, then the tooling may need to additionally qualify the replacement.
Without information about how the callee was found, the tooling is left scratching it's head. Additionally, we want to be able to match ADL calls as quickly as possible, which means avoiding computing the answer on the fly.
This patch changes `CallExpr` to store whether it's callee was found using ADL. It does not change the size of any AST nodes.
Reviewers: fowles, rsmith, klimek, shafik
Reviewed By: rsmith
Subscribers: aaron.ballman, riccibruno, calabrese, titus, cfe-commits
Differential Revision: https://reviews.llvm.org/D55534
llvm-svn: 348977
Address spaces are cast into generic before invoking the constructor.
Added support for a trailing Qualifiers object in FunctionProtoType.
Differential Revision: https://reviews.llvm.org/D54862
llvm-svn: 348927
Use zip_longest in two locations that compare iterator ranges.
zip_longest allows the iteration using a range-based for-loop and to be
symmetric over both ranges instead of prioritizing one over the other.
In that latter case code have to handle the case that the first is
longer than the second, the second is longer than the first, and both
are of the same length, which must partially be checked after the loop.
With zip_longest, this becomes an element comparison within the loop
like the comparison of the elements themselves. The symmetry makes it
clearer that neither the first and second iterators are handled
differently. The iterators are not event used directly anymore, just
the ranges.
Differential Revision: https://reviews.llvm.org/D55468
llvm-svn: 348762
When debugging a boost build with a modified
version of Clang, I discovered that the PTH implementation
stores TokenKind in 8 bits. However, we currently have 368
TokenKinds.
The result is that the value gets truncated and the wrong token
gets picked up when including PTH files. It seems that this will
go wrong every time someone uses a token that uses the 9th bit.
Upon asking on IRC, it was brought up that this was a highly
experimental features that was considered a failure. I discovered
via googling that BoostBuild (mostly Boost.Math) is the only user of
this
feature, using the CC1 flag directly. I believe that this can be
transferred over to normal PCH with minimal effort:
https://github.com/boostorg/build/issues/367
Based on advice on IRC and research showing that this is a nearly
completely unused feature, this patch removes it entirely.
Note: I considered leaving the build-flags in place and making them
emit an error/warning, however since I've basically identified and
warned the only user, it seemed better to just remove them.
Differential Revision: https://reviews.llvm.org/D54547
Change-Id: If32744275ef1f585357bd6c1c813d96973c4d8d9
llvm-svn: 348266
Remove the pointless "+ 0" which I added for some reason when
modifying these statement/expression classes since it looks
like this is a typo. Following the suggestion of aaron.ballman
in D54902. NFC.
llvm-svn: 348150
CallExpr::setNumArgs is the only thing that prevents storing the arguments
in a trailing array. There is only 3 places in Sema where setNumArgs is called.
D54900 dealt with one of them.
This patch remove the other two calls to setNumArgs in ConvertArgumentsForCall.
To do this we do the following changes:
1.) Replace the first call to setNumArgs by an assertion since we are moving the
responsability to allocate enough space for the arguments from
Sema::ConvertArgumentsForCall to its callers
(which are Sema::BuildCallToMemberFunction, and Sema::BuildResolvedCallExpr).
2.) Add a new member function CallExpr::shrinkNumArgs, which can only be used
to drop arguments and then replace the second call to setNumArgs by
shrinkNumArgs.
3.) Add a new defaulted parameter MinNumArgs to CallExpr and its derived
classes which specifies a minimum number of argument slots to allocate.
The actual number of arguments slots allocated will be
max(number of args, MinNumArgs) with the extra args nulled. Note that
after the creation of the call expression all of the arguments will be
non-null. It is just during the creation of the call expression that some of
the last arguments can be temporarily null, until filled by default arguments.
4.) Update Sema::BuildCallToMemberFunction by passing the number of parameters
in the function prototype to the constructor of CXXMemberCallExpr. Here the
change is pretty straightforward.
5.) Update Sema::BuildResolvedCallExpr. Here the change is more complicated
since the type-checking for the function type was done after the creation of
the call expression. We need to move this before the creation of the call
expression, and then pass the number of parameters in the function prototype
(if any) to the constructor of the call expression.
6.) Update the deserialization of CallExpr and its derived classes.
Differential Revision: https://reviews.llvm.org/D54902
Reviewed By: aaron.ballman
llvm-svn: 348145
Use the newly available space in the bit-fields of Stmt
and store the expressions in a trailing array. This saves
2 pointer per ParenListExpr.
Differential Revision: https://reviews.llvm.org/D54675
Reviewed By: rjmccall
llvm-svn: 347320