2010-08-19 07:56:31 +08:00
|
|
|
//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
|
2009-04-27 14:20:01 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2009-04-27 14:20:01 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-08-10 07:08:25 +08:00
|
|
|
///
|
|
|
|
/// \file
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Implements serialization for Statements and Expressions.
|
2013-08-10 07:08:25 +08:00
|
|
|
///
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:37 +08:00
|
|
|
#include "clang/Serialization/ASTWriter.h"
|
2012-07-05 04:19:54 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-09-10 07:08:42 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2009-04-27 14:20:01 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2011-01-15 09:15:58 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2009-04-27 14:20:01 +08:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2013-05-03 08:10:13 +08:00
|
|
|
#include "clang/Lex/Token.h"
|
2019-07-04 06:40:07 +08:00
|
|
|
#include "llvm/Bitstream/BitstreamWriter.h"
|
2009-04-27 14:20:01 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Statement/expression serialization
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-30 16:49:18 +08:00
|
|
|
namespace clang {
|
2013-07-19 11:13:43 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
|
2010-08-19 07:56:21 +08:00
|
|
|
ASTWriter &Writer;
|
2016-04-07 01:06:00 +08:00
|
|
|
ASTRecordWriter Record;
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
serialization::StmtCode Code;
|
2011-06-03 10:27:19 +08:00
|
|
|
unsigned AbbrevToUse;
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
public:
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
|
2016-04-07 01:06:00 +08:00
|
|
|
: Writer(Writer), Record(Writer, Record),
|
|
|
|
Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
|
|
|
|
|
|
|
|
ASTStmtWriter(const ASTStmtWriter&) = delete;
|
|
|
|
|
2016-04-07 04:12:34 +08:00
|
|
|
uint64_t Emit() {
|
2016-04-07 01:06:00 +08:00
|
|
|
assert(Code != serialization::STMT_NULL_PTR &&
|
|
|
|
"unhandled sub-statement writing AST file");
|
|
|
|
return Record.EmitStmt(Code, AbbrevToUse);
|
|
|
|
}
|
2012-01-27 17:46:47 +08:00
|
|
|
|
2015-12-30 02:15:14 +08:00
|
|
|
void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
|
|
|
|
const TemplateArgumentLoc *Args);
|
2009-04-27 14:20:01 +08:00
|
|
|
|
|
|
|
void VisitStmt(Stmt *S);
|
2011-07-15 15:00:14 +08:00
|
|
|
#define STMT(Type, Base) \
|
|
|
|
void Visit##Type(Type *);
|
|
|
|
#include "clang/AST/StmtNodes.inc"
|
2009-04-27 14:20:01 +08:00
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2015-12-30 02:15:14 +08:00
|
|
|
void ASTStmtWriter::AddTemplateKWAndArgsInfo(
|
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
|
|
|
|
Record.AddSourceLocation(ArgInfo.LAngleLoc);
|
|
|
|
Record.AddSourceLocation(ArgInfo.RAngleLoc);
|
2015-12-30 02:15:14 +08:00
|
|
|
for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTemplateArgumentLoc(Args[i]);
|
2010-06-28 17:31:48 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitStmt(Stmt *S) {
|
[clang][OpeMP] Model OpenMP structured-block in AST (PR40563)
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
2019-03-21 00:32:36 +08:00
|
|
|
Record.push_back(S->StmtBits.IsOMPStructuredBlock);
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getSemiLoc());
|
[AST] Widen the bit-fields of Stmt to 8 bytes.
Although some classes are using the tail padding of Stmt, most of
them are not. In particular the expression classes are not using it
since there is Expr in between, and Expr contains a single pointer.
This patch widen the bit-fields to Stmt to 8 bytes and move some
data from NullStmt, CompoundStmt, LabelStmt, AttributedStmt, SwitchStmt,
WhileStmt, DoStmt, ForStmt, GotoStmt, ContinueStmt, BreakStmt
and ReturnStmt to the newly available space.
In itself this patch do not achieve much but I plan to go through each of
the classes in the statement/expression hierarchy and use this newly
available space. A quick estimation gives me that this should shrink the
size of the statement/expression hierarchy by >10% when parsing all of Boost.
Differential Revision: https://reviews.llvm.org/D53604
Reviewed By: rjmccall
llvm-svn: 345459
2018-10-28 02:43:27 +08:00
|
|
|
Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_NULL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->size());
|
2014-03-17 22:19:37 +08:00
|
|
|
for (auto *CS : S->body())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(CS);
|
|
|
|
Record.AddSourceLocation(S->getLBracLoc());
|
|
|
|
Record.AddSourceLocation(S->getRBracLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_COMPOUND;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Record.push_back(Writer.getSwitchCaseID(S));
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
|
|
|
Record.AddSourceLocation(S->getColonLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitSwitchCase(S);
|
2018-10-28 20:30:53 +08:00
|
|
|
Record.push_back(S->caseStmtIsGNURange());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getLHS());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
2018-10-28 20:30:53 +08:00
|
|
|
if (S->caseStmtIsGNURange()) {
|
|
|
|
Record.AddStmt(S->getRHS());
|
|
|
|
Record.AddSourceLocation(S->getEllipsisLoc());
|
|
|
|
}
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CASE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitSwitchCase(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getSubStmt());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_DEFAULT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(S->getDecl());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
|
|
|
Record.AddSourceLocation(S->getIdentLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_LABEL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-04-14 08:33:13 +08:00
|
|
|
void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
|
|
|
|
VisitStmt(S);
|
2012-07-09 18:04:07 +08:00
|
|
|
Record.push_back(S->getAttrs().size());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddAttributes(S->getAttrs());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
|
|
|
Record.AddSourceLocation(S->getAttrLoc());
|
2012-04-14 08:33:13 +08:00
|
|
|
Code = serialization::STMT_ATTRIBUTED;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2018-10-28 05:12:20 +08:00
|
|
|
|
|
|
|
bool HasElse = S->getElse() != nullptr;
|
|
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
|
|
bool HasInit = S->getInit() != nullptr;
|
|
|
|
|
2016-06-24 03:16:49 +08:00
|
|
|
Record.push_back(S->isConstexpr());
|
2018-10-28 05:12:20 +08:00
|
|
|
Record.push_back(HasElse);
|
|
|
|
Record.push_back(HasVar);
|
|
|
|
Record.push_back(HasInit);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getThen());
|
2018-10-28 05:12:20 +08:00
|
|
|
if (HasElse)
|
|
|
|
Record.AddStmt(S->getElse());
|
|
|
|
if (HasVar)
|
|
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
|
|
if (HasInit)
|
|
|
|
Record.AddStmt(S->getInit());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getIfLoc());
|
2018-10-28 05:12:20 +08:00
|
|
|
if (HasElse)
|
|
|
|
Record.AddSourceLocation(S->getElseLoc());
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_IF;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2018-10-30 00:12:37 +08:00
|
|
|
|
|
|
|
bool HasInit = S->getInit() != nullptr;
|
|
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
|
|
Record.push_back(HasInit);
|
|
|
|
Record.push_back(HasVar);
|
|
|
|
Record.push_back(S->isAllEnumCasesCovered());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getBody());
|
2018-10-30 00:12:37 +08:00
|
|
|
if (HasInit)
|
|
|
|
Record.AddStmt(S->getInit());
|
|
|
|
if (HasVar)
|
|
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getSwitchLoc());
|
2018-10-30 00:12:37 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
for (SwitchCase *SC = S->getSwitchCaseList(); SC;
|
2009-04-27 14:20:01 +08:00
|
|
|
SC = SC->getNextSwitchCase())
|
2010-06-29 06:28:35 +08:00
|
|
|
Record.push_back(Writer.RecordSwitchCaseID(SC));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_SWITCH;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2018-10-30 21:42:41 +08:00
|
|
|
|
|
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
|
|
Record.push_back(HasVar);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getBody());
|
2018-10-30 21:42:41 +08:00
|
|
|
if (HasVar)
|
|
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getWhileLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_WHILE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getBody());
|
|
|
|
Record.AddSourceLocation(S->getDoLoc());
|
|
|
|
Record.AddSourceLocation(S->getWhileLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_DO;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitForStmt(ForStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getInit());
|
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
|
|
Record.AddStmt(S->getInc());
|
|
|
|
Record.AddStmt(S->getBody());
|
|
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_FOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(S->getLabel());
|
|
|
|
Record.AddSourceLocation(S->getGotoLoc());
|
|
|
|
Record.AddSourceLocation(S->getLabelLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_GOTO;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getGotoLoc());
|
|
|
|
Record.AddSourceLocation(S->getStarLoc());
|
|
|
|
Record.AddStmt(S->getTarget());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_INDIRECT_GOTO;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getContinueLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CONTINUE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getBreakLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_BREAK;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2018-10-30 22:40:49 +08:00
|
|
|
|
|
|
|
bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
|
|
|
|
Record.push_back(HasNRVOCandidate);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getRetValue());
|
2018-10-30 22:40:49 +08:00
|
|
|
if (HasNRVOCandidate)
|
|
|
|
Record.AddDeclRef(S->getNRVOCandidate());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getReturnLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_RETURN;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2018-08-10 05:05:56 +08:00
|
|
|
Record.AddSourceLocation(S->getBeginLoc());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getEndLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
DeclGroupRef DG = S->getDeclGroup();
|
|
|
|
for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(*D);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_DECL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2013-05-03 08:10:13 +08:00
|
|
|
void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getNumOutputs());
|
|
|
|
Record.push_back(S->getNumInputs());
|
|
|
|
Record.push_back(S->getNumClobbers());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getAsmLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(S->isVolatile());
|
|
|
|
Record.push_back(S->isSimple());
|
2013-05-03 08:10:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
|
|
|
|
VisitAsmStmt(S);
|
2019-06-03 23:57:25 +08:00
|
|
|
Record.push_back(S->getNumLabels());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
|
|
Record.AddStmt(S->getAsmString());
|
2009-04-27 14:20:01 +08:00
|
|
|
|
|
|
|
// Outputs
|
2018-07-31 03:24:48 +08:00
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddIdentifierRef(S->getOutputIdentifier(I));
|
|
|
|
Record.AddStmt(S->getOutputConstraintLiteral(I));
|
|
|
|
Record.AddStmt(S->getOutputExpr(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddIdentifierRef(S->getInputIdentifier(I));
|
|
|
|
Record.AddStmt(S->getInputConstraintLiteral(I));
|
|
|
|
Record.AddStmt(S->getInputExpr(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clobbers
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getClobberStringLiteral(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2019-06-03 23:57:25 +08:00
|
|
|
// Labels
|
|
|
|
for (auto *E : S->labels()) Record.AddStmt(E);
|
|
|
|
|
2012-08-25 08:11:56 +08:00
|
|
|
Code = serialization::STMT_GCCASM;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-06-12 04:47:18 +08:00
|
|
|
void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
|
2013-05-03 08:10:13 +08:00
|
|
|
VisitAsmStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getLBraceLoc());
|
|
|
|
Record.AddSourceLocation(S->getEndLoc());
|
2013-05-03 08:10:13 +08:00
|
|
|
Record.push_back(S->getNumAsmToks());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddString(S->getAsmString());
|
2013-05-03 08:10:13 +08:00
|
|
|
|
|
|
|
// Tokens
|
|
|
|
for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
|
2016-04-07 01:06:00 +08:00
|
|
|
// FIXME: Move this to ASTRecordWriter?
|
|
|
|
Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
|
2013-05-03 08:10:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clobbers
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddString(S->getClobber(I));
|
2013-05-03 08:10:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Outputs
|
2017-07-26 02:01:49 +08:00
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getOutputExpr(I));
|
|
|
|
Record.AddString(S->getOutputConstraint(I));
|
2013-05-03 08:10:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getInputExpr(I));
|
|
|
|
Record.AddString(S->getInputConstraint(I));
|
2013-05-03 08:10:13 +08:00
|
|
|
}
|
2012-08-25 07:51:02 +08:00
|
|
|
|
|
|
|
Code = serialization::STMT_MSASM;
|
2012-06-12 04:47:18 +08:00
|
|
|
}
|
|
|
|
|
2017-07-26 02:01:49 +08:00
|
|
|
void ASTStmtWriter::VisitCoroutineBodyStmt(CoroutineBodyStmt *CoroStmt) {
|
|
|
|
VisitStmt(CoroStmt);
|
|
|
|
Record.push_back(CoroStmt->getParamMoves().size());
|
|
|
|
for (Stmt *S : CoroStmt->children())
|
|
|
|
Record.AddStmt(S);
|
|
|
|
Code = serialization::STMT_COROUTINE_BODY;
|
2015-10-27 14:02:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
|
2017-07-26 02:01:49 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
|
|
|
Record.AddStmt(S->getOperand());
|
|
|
|
Record.AddStmt(S->getPromiseCall());
|
|
|
|
Record.push_back(S->isImplicit());
|
|
|
|
Code = serialization::STMT_CORETURN;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getKeywordLoc());
|
|
|
|
for (Stmt *S : E->children())
|
|
|
|
Record.AddStmt(S);
|
|
|
|
Record.AddStmt(E->getOpaqueValue());
|
2015-10-27 14:02:45 +08:00
|
|
|
}
|
|
|
|
|
2017-07-26 02:01:49 +08:00
|
|
|
void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
|
|
|
|
VisitCoroutineSuspendExpr(E);
|
|
|
|
Record.push_back(E->isImplicit());
|
|
|
|
Code = serialization::EXPR_COAWAIT;
|
2015-10-27 14:02:45 +08:00
|
|
|
}
|
|
|
|
|
2017-07-26 02:01:49 +08:00
|
|
|
void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
|
|
|
|
VisitCoroutineSuspendExpr(E);
|
|
|
|
Code = serialization::EXPR_COYIELD;
|
2017-03-07 07:38:15 +08:00
|
|
|
}
|
|
|
|
|
2017-07-26 02:01:49 +08:00
|
|
|
void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getKeywordLoc());
|
|
|
|
for (Stmt *S : E->children())
|
|
|
|
Record.AddStmt(S);
|
|
|
|
Code = serialization::EXPR_DEPENDENT_COAWAIT;
|
2015-10-27 14:02:45 +08:00
|
|
|
}
|
|
|
|
|
2013-04-17 02:53:08 +08:00
|
|
|
void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
|
|
|
|
VisitStmt(S);
|
2013-05-04 03:20:19 +08:00
|
|
|
// NumCaptures
|
|
|
|
Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
|
|
|
|
|
2013-05-04 11:59:06 +08:00
|
|
|
// CapturedDecl and captured region kind
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(S->getCapturedDecl());
|
2013-05-04 11:59:06 +08:00
|
|
|
Record.push_back(S->getCapturedRegionKind());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(S->getCapturedRecordDecl());
|
2013-05-04 03:20:19 +08:00
|
|
|
|
|
|
|
// Capture inits
|
2014-03-15 03:41:04 +08:00
|
|
|
for (auto *I : S->capture_inits())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2013-05-04 03:20:19 +08:00
|
|
|
|
|
|
|
// Body
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCapturedStmt());
|
2013-05-04 03:20:19 +08:00
|
|
|
|
|
|
|
// Captures
|
2014-03-15 02:08:33 +08:00
|
|
|
for (const auto &I : S->captures()) {
|
2014-10-29 20:21:55 +08:00
|
|
|
if (I.capturesThis() || I.capturesVariableArrayType())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(nullptr);
|
2013-05-04 03:20:19 +08:00
|
|
|
else
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(I.getCapturedVar());
|
2014-03-15 02:08:33 +08:00
|
|
|
Record.push_back(I.getCaptureKind());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(I.getLocation());
|
2013-05-04 03:20:19 +08:00
|
|
|
}
|
2013-04-17 02:53:08 +08:00
|
|
|
|
2013-05-04 03:20:19 +08:00
|
|
|
Code = serialization::STMT_CAPTURED;
|
2013-04-17 02:53:08 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitExpr(Expr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeRef(E->getType());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isTypeDependent());
|
|
|
|
Record.push_back(E->isValueDependent());
|
2011-07-01 09:22:09 +08:00
|
|
|
Record.push_back(E->isInstantiationDependent());
|
Variadic templates: extend Type, NestedNameSpecifier, TemplateName,
and TemplateArgument with an operation that determines whether there
are any unexpanded parameter packs within that construct. Use this
information to diagnose the appearance of the names of parameter packs
that have not been expanded (C++ [temp.variadic]p5). Since this
property is checked often (every declaration, ever expression
statement, etc.), we extend Type and Expr with a bit storing the
result of this computation, rather than walking the AST each time to
determine whether any unexpanded parameter packs occur.
This commit is deficient in several ways, which will be remedied with
future commits:
- Expr has a bit to store the presence of an unexpanded parameter
pack, but it is never set.
- The error messages don't point out where the unexpanded parameter
packs were named in the type/expression, but they should.
- We don't check for unexpanded parameter packs in all of the places
where we should.
- Testing is sparse, pending the resolution of the above three
issues.
llvm-svn: 121724
2010-12-14 06:49:22 +08:00
|
|
|
Record.push_back(E->containsUnexpandedParameterPack());
|
2010-11-18 14:31:45 +08:00
|
|
|
Record.push_back(E->getValueKind());
|
|
|
|
Record.push_back(E->getObjectKind());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2018-10-31 11:48:47 +08:00
|
|
|
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
|
|
|
|
VisitExpr(E);
|
[clang] Add storage for APValue in ConstantExpr
Summary:
When using ConstantExpr we often need the result of the expression to be kept in the AST. Currently this is done on a by the node that needs the result and has been done multiple times for enumerator, for constexpr variables... . This patch adds to ConstantExpr the ability to store the result of evaluating the expression. no functional changes expected.
Changes:
- Add trailling object to ConstantExpr that can hold an APValue or an uint64_t. the uint64_t is here because most ConstantExpr yield integral values so there is an optimized layout for integral values.
- Add basic* serialization support for the trailing result.
- Move conversion functions from an enum to a fltSemantics from clang::FloatingLiteral to llvm::APFloatBase. this change is to make it usable for serializing APValues.
- Add basic* Import support for the trailing result.
- ConstantExpr created in CheckConvertedConstantExpression now stores the result in the ConstantExpr Node.
- Adapt AST dump to print the result when present.
basic* : None, Indeterminate, Int, Float, FixedPoint, ComplexInt, ComplexFloat,
the result is not yet used anywhere but for -ast-dump.
Reviewers: rsmith, martong, shafik
Reviewed By: rsmith
Subscribers: rnkovacs, hiraditya, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D62399
llvm-svn: 363493
2019-06-15 18:24:47 +08:00
|
|
|
Record.push_back(static_cast<uint64_t>(E->ConstantExprBits.ResultKind));
|
|
|
|
switch (E->ConstantExprBits.ResultKind) {
|
|
|
|
case ConstantExpr::RSK_Int64:
|
|
|
|
Record.push_back(E->Int64Result());
|
|
|
|
Record.push_back(E->ConstantExprBits.IsUnsigned |
|
|
|
|
E->ConstantExprBits.BitWidth << 1);
|
|
|
|
break;
|
|
|
|
case ConstantExpr::RSK_APValue:
|
|
|
|
Record.AddAPValue(E->APValueResult());
|
|
|
|
}
|
2018-10-31 11:48:47 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Code = serialization::EXPR_CONSTANT;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2018-10-28 03:21:19 +08:00
|
|
|
|
|
|
|
bool HasFunctionName = E->getFunctionName() != nullptr;
|
|
|
|
Record.push_back(HasFunctionName);
|
|
|
|
Record.push_back(E->getIdentKind()); // FIXME: stable encoding
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2018-10-28 03:21:19 +08:00
|
|
|
if (HasFunctionName)
|
|
|
|
Record.AddStmt(E->getFunctionName());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_PREDEFINED;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-07-08 21:09:47 +08:00
|
|
|
|
|
|
|
Record.push_back(E->hasQualifier());
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
Record.push_back(E->getDecl() != E->getFoundDecl());
|
2012-01-27 17:46:47 +08:00
|
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
2011-10-05 15:56:41 +08:00
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
2015-01-12 18:17:46 +08:00
|
|
|
Record.push_back(E->refersToEnclosingVariableOrCapture());
|
2019-06-12 01:50:32 +08:00
|
|
|
Record.push_back(E->isNonOdrUse());
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2011-02-04 20:01:24 +08:00
|
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
|
|
Record.push_back(NumTemplateArgs);
|
|
|
|
}
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2011-06-03 10:27:19 +08:00
|
|
|
DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
|
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
|
2011-06-03 10:27:19 +08:00
|
|
|
(E->getDecl() == E->getFoundDecl()) &&
|
2019-06-12 01:50:32 +08:00
|
|
|
nk == DeclarationName::Identifier &&
|
|
|
|
!E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse()) {
|
2011-06-03 10:27:19 +08:00
|
|
|
AbbrevToUse = Writer.getDeclRefExprAbbrev();
|
|
|
|
}
|
|
|
|
|
2011-03-07 02:19:42 +08:00
|
|
|
if (E->hasQualifier())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
2011-03-07 02:19:42 +08:00
|
|
|
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
if (E->getDecl() != E->getFoundDecl())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getFoundDecl());
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
2015-12-30 02:15:14 +08:00
|
|
|
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
2011-03-07 02:19:42 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getDecl());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_DECL_REF;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddAPInt(E->getValue());
|
2011-06-03 10:27:19 +08:00
|
|
|
|
|
|
|
if (E->getValue().getBitWidth() == 32) {
|
|
|
|
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_INTEGER_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2018-06-21 01:19:40 +08:00
|
|
|
void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddAPInt(E->getValue());
|
|
|
|
Code = serialization::EXPR_INTEGER_LITERAL;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2013-01-22 17:46:51 +08:00
|
|
|
Record.push_back(E->getRawSemantics());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isExact());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddAPFloat(E->getValue());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_FLOATING_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_IMAGINARY_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2018-11-16 01:31:16 +08:00
|
|
|
|
|
|
|
// Store the various bits of data of StringLiteral.
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->getNumConcatenated());
|
2018-11-16 01:31:16 +08:00
|
|
|
Record.push_back(E->getLength());
|
|
|
|
Record.push_back(E->getCharByteWidth());
|
2011-07-27 13:40:30 +08:00
|
|
|
Record.push_back(E->getKind());
|
2011-04-14 08:40:03 +08:00
|
|
|
Record.push_back(E->isPascal());
|
2018-11-16 01:31:16 +08:00
|
|
|
|
|
|
|
// Store the trailing array of SourceLocation.
|
2009-04-27 14:20:01 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getStrTokenLoc(I));
|
2018-11-16 01:31:16 +08:00
|
|
|
|
|
|
|
// Store the trailing array of char holding the string data.
|
|
|
|
StringRef StrData = E->getBytes();
|
|
|
|
for (unsigned I = 0, N = E->getByteLength(); I != N; ++I)
|
|
|
|
Record.push_back(StrData[I]);
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_STRING_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2011-07-27 13:40:30 +08:00
|
|
|
Record.push_back(E->getKind());
|
2011-06-03 10:27:19 +08:00
|
|
|
|
|
|
|
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CHARACTER_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLParen());
|
|
|
|
Record.AddSourceLocation(E->getRParen());
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_PAREN;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
|
2010-06-30 16:49:18 +08:00
|
|
|
VisitExpr(E);
|
2018-11-21 00:20:40 +08:00
|
|
|
Record.push_back(E->getNumExprs());
|
|
|
|
for (auto *SubStmt : E->exprs())
|
|
|
|
Record.AddStmt(SubStmt);
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_PAREN_LIST;
|
2010-06-30 16:49:18 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2018-04-16 16:31:08 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.push_back(E->canOverflow());
|
|
|
|
Code = serialization::EXPR_UNARY_OPERATOR;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumComponents());
|
|
|
|
Record.push_back(E->getNumExpressions());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
2015-12-30 06:31:18 +08:00
|
|
|
const OffsetOfNode &ON = E->getComponent(I);
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
Record.push_back(ON.getKind()); // FIXME: Stable encoding
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(ON.getSourceRange().getBegin());
|
|
|
|
Record.AddSourceLocation(ON.getSourceRange().getEnd());
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
switch (ON.getKind()) {
|
2015-12-30 06:31:18 +08:00
|
|
|
case OffsetOfNode::Array:
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
Record.push_back(ON.getArrayExprIndex());
|
|
|
|
break;
|
2015-12-30 06:31:18 +08:00
|
|
|
|
|
|
|
case OffsetOfNode::Field:
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(ON.getField());
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
break;
|
2015-12-30 06:31:18 +08:00
|
|
|
|
|
|
|
case OffsetOfNode::Identifier:
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddIdentifierRef(ON.getFieldName());
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
break;
|
2015-12-30 06:31:18 +08:00
|
|
|
|
|
|
|
case OffsetOfNode::Base:
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddCXXBaseSpecifier(*ON.getBase());
|
2010-04-29 08:18:15 +08:00
|
|
|
break;
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getIndexExpr(I));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OFFSETOF;
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
}
|
|
|
|
|
2011-03-12 03:24:49 +08:00
|
|
|
void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2011-03-12 03:24:49 +08:00
|
|
|
Record.push_back(E->getKind());
|
2009-04-27 14:20:01 +08:00
|
|
|
if (E->isArgumentType())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
|
2009-04-27 14:20:01 +08:00
|
|
|
else {
|
|
|
|
Record.push_back(0);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getArgumentExpr());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_SIZEOF_ALIGN_OF;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2015-08-25 22:24:04 +08:00
|
|
|
void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getLowerBound());
|
|
|
|
Record.AddStmt(E->getLength());
|
|
|
|
Record.AddSourceLocation(E->getColonLoc());
|
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2015-08-25 22:24:04 +08:00
|
|
|
Code = serialization::EXPR_OMP_ARRAY_SECTION;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumArgs());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddStmt(E->getCallee());
|
2009-04-27 14:20:01 +08:00
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
|
|
Arg != ArgEnd; ++Arg)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(*Arg);
|
[AST] Store "UsesADL" information in CallExpr.
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
2018-12-13 05:50:55 +08:00
|
|
|
Record.push_back(static_cast<unsigned>(E->getADLCallKind()));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CALL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
2019-06-07 07:24:15 +08:00
|
|
|
VisitExpr(E);
|
2019-06-05 19:46:57 +08:00
|
|
|
|
2019-06-07 07:24:15 +08:00
|
|
|
bool HasQualifier = E->hasQualifier();
|
|
|
|
bool HasFoundDecl =
|
|
|
|
E->hasQualifierOrFoundDecl() &&
|
|
|
|
(E->getFoundDecl().getDecl() != E->getMemberDecl() ||
|
|
|
|
E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess());
|
|
|
|
bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
|
|
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
|
|
|
|
|
|
// Write these first for easy access when deserializing, as they affect the
|
|
|
|
// size of the MemberExpr.
|
|
|
|
Record.push_back(HasQualifier);
|
|
|
|
Record.push_back(HasFoundDecl);
|
|
|
|
Record.push_back(HasTemplateInfo);
|
|
|
|
Record.push_back(NumTemplateArgs);
|
2019-06-05 19:46:57 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddDeclRef(E->getMemberDecl());
|
2019-06-07 07:24:15 +08:00
|
|
|
Record.AddDeclarationNameLoc(E->MemberDNLoc,
|
|
|
|
E->getMemberDecl()->getDeclName());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getMemberLoc());
|
2015-05-01 10:04:32 +08:00
|
|
|
Record.push_back(E->isArrow());
|
2019-06-07 07:24:15 +08:00
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
2019-06-12 01:50:36 +08:00
|
|
|
Record.push_back(E->isNonOdrUse());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2019-06-07 07:24:15 +08:00
|
|
|
|
|
|
|
if (HasFoundDecl) {
|
|
|
|
DeclAccessPair FoundDecl = E->getFoundDecl();
|
|
|
|
Record.AddDeclRef(FoundDecl.getDecl());
|
|
|
|
Record.push_back(FoundDecl.getAccess());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (HasQualifier)
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
|
|
|
|
if (HasTemplateInfo)
|
|
|
|
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
|
|
|
|
2015-05-01 10:04:32 +08:00
|
|
|
Code = serialization::EXPR_MEMBER;
|
2009-07-25 01:54:45 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
|
2009-07-25 01:54:45 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddSourceLocation(E->getIsaMemberLoc());
|
|
|
|
Record.AddSourceLocation(E->getOpLoc());
|
2009-07-25 01:54:45 +08:00
|
|
|
Record.push_back(E->isArrow());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_ISA;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
void ASTStmtWriter::
|
|
|
|
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2011-06-16 07:02:42 +08:00
|
|
|
Record.push_back(E->shouldCopy());
|
|
|
|
Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
|
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getBridgeKeywordLoc());
|
2011-06-16 07:02:42 +08:00
|
|
|
Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
|
|
|
|
Code = serialization::EXPR_OBJC_BRIDGED_CAST;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-08-07 14:22:56 +08:00
|
|
|
Record.push_back(E->path_size());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2009-07-31 08:48:10 +08:00
|
|
|
Record.push_back(E->getCastKind()); // FIXME: stable encoding
|
2010-08-07 14:22:56 +08:00
|
|
|
|
|
|
|
for (CastExpr::path_iterator
|
|
|
|
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddCXXBaseSpecifier(**PI);
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2017-03-28 03:17:25 +08:00
|
|
|
Record.push_back(E->getFPFeatures().getInt());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_BINARY_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitBinaryOperator(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeRef(E->getComputationLHSType());
|
|
|
|
Record.AddTypeRef(E->getComputationResultType());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getCond());
|
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getQuestionLoc());
|
|
|
|
Record.AddSourceLocation(E->getColonLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CONDITIONAL_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 18:25:35 +08:00
|
|
|
void
|
|
|
|
ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getOpaqueValue());
|
|
|
|
Record.AddStmt(E->getCommon());
|
|
|
|
Record.AddStmt(E->getCond());
|
|
|
|
Record.AddStmt(E->getTrueExpr());
|
|
|
|
Record.AddStmt(E->getFalseExpr());
|
|
|
|
Record.AddSourceLocation(E->getQuestionLoc());
|
|
|
|
Record.AddSourceLocation(E->getColonLoc());
|
2011-02-17 18:25:35 +08:00
|
|
|
Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitCastExpr(E);
|
[AST] Sink 'part of explicit cast' down into ImplicitCastExpr
Summary:
As discussed in IRC with @rsmith, it is slightly not good to keep that in the `CastExpr` itself:
Given the explicit cast, which is represented in AST as an `ExplicitCastExpr` + `ImplicitCastExpr`'s,
only the `ImplicitCastExpr`'s will be marked as `PartOfExplicitCast`, but not the `ExplicitCastExpr` itself.
Thus, it is only ever `true` for `ImplicitCastExpr`'s, so we don't need to write/read/dump it for `ExplicitCastExpr`'s.
We don't need to worry that we write the `PartOfExplicitCast` in PCH after `CastExpr::path_iterator`,
since the `ExprImplicitCastAbbrev` is only used when the `NumBaseSpecs == 0`, i.e. there is no 'path'.
Reviewers: rsmith, rjmccall, erichkeane, aaron.ballman
Reviewed By: rsmith, erichkeane
Subscribers: vsk, cfe-commits, rsmith
Tags: #clang
Differential Revision: https://reviews.llvm.org/D49838
llvm-svn: 338108
2018-07-27 15:27:14 +08:00
|
|
|
Record.push_back(E->isPartOfExplicitCast());
|
2014-07-27 12:19:32 +08:00
|
|
|
|
|
|
|
if (E->path_size() == 0)
|
|
|
|
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_IMPLICIT_CAST;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitCastExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CSTYLE_CAST;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddStmt(E->getInitializer());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isFileScope());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_COMPOUND_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddIdentifierRef(&E->getAccessor());
|
|
|
|
Record.AddSourceLocation(E->getAccessorLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2012-11-09 02:41:43 +08:00
|
|
|
// NOTE: only add the (possibly null) syntactic form.
|
|
|
|
// No need to serialize the isSemanticForm flag and the semantic form.
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSyntacticForm());
|
|
|
|
Record.AddSourceLocation(E->getLBraceLoc());
|
|
|
|
Record.AddSourceLocation(E->getRBraceLoc());
|
2011-04-21 08:27:41 +08:00
|
|
|
bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
|
|
|
|
Record.push_back(isArrayFiller);
|
|
|
|
if (isArrayFiller)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getArrayFiller());
|
2011-04-21 08:27:41 +08:00
|
|
|
else
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getInitializedFieldInUnion());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->hadArrayRangeDesignator());
|
2011-04-22 13:29:30 +08:00
|
|
|
Record.push_back(E->getNumInits());
|
|
|
|
if (isArrayFiller) {
|
|
|
|
// ArrayFiller may have filled "holes" due to designated initializer.
|
|
|
|
// Replace them by 0 to indicate that the filler goes in that place.
|
|
|
|
Expr *filler = E->getArrayFiller();
|
|
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
|
2011-04-22 13:29:30 +08:00
|
|
|
} else {
|
|
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getInit(I));
|
2011-04-22 13:29:30 +08:00
|
|
|
}
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_INIT_LIST;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSubExprs());
|
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr(I));
|
|
|
|
Record.AddSourceLocation(E->getEqualOrColonLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->usesGNUSyntax());
|
2016-06-23 08:15:04 +08:00
|
|
|
for (const DesignatedInitExpr::Designator &D : E->designators()) {
|
|
|
|
if (D.isFieldDesignator()) {
|
|
|
|
if (FieldDecl *Field = D.getField()) {
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_FIELD_DECL);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(Field);
|
2009-04-27 14:20:01 +08:00
|
|
|
} else {
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_FIELD_NAME);
|
2016-06-23 08:15:04 +08:00
|
|
|
Record.AddIdentifierRef(D.getFieldName());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
2016-06-23 08:15:04 +08:00
|
|
|
Record.AddSourceLocation(D.getDotLoc());
|
|
|
|
Record.AddSourceLocation(D.getFieldLoc());
|
|
|
|
} else if (D.isArrayDesignator()) {
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_ARRAY);
|
2016-06-23 08:15:04 +08:00
|
|
|
Record.push_back(D.getFirstExprIndex());
|
|
|
|
Record.AddSourceLocation(D.getLBracketLoc());
|
|
|
|
Record.AddSourceLocation(D.getRBracketLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
} else {
|
2016-06-23 08:15:04 +08:00
|
|
|
assert(D.isArrayRangeDesignator() && "Unknown designator");
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_ARRAY_RANGE);
|
2016-06-23 08:15:04 +08:00
|
|
|
Record.push_back(D.getFirstExprIndex());
|
|
|
|
Record.AddSourceLocation(D.getLBracketLoc());
|
|
|
|
Record.AddSourceLocation(D.getEllipsisLoc());
|
|
|
|
Record.AddSourceLocation(D.getRBracketLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
}
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_DESIGNATED_INIT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2015-06-10 08:27:52 +08:00
|
|
|
void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getUpdater());
|
2015-06-10 08:27:52 +08:00
|
|
|
Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Code = serialization::EXPR_NO_INIT;
|
|
|
|
}
|
|
|
|
|
2016-12-12 10:53:20 +08:00
|
|
|
void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddStmt(E->SubExprs[0]);
|
|
|
|
Record.AddStmt(E->SubExprs[1]);
|
|
|
|
Code = serialization::EXPR_ARRAY_INIT_LOOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Code = serialization::EXPR_ARRAY_INIT_INDEX;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2015-09-18 04:55:33 +08:00
|
|
|
Record.push_back(E->isMicrosoftABI());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_VA_ARG;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
Implement __builtin_LINE() et. al. to support source location capture.
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
2019-05-17 05:04:15 +08:00
|
|
|
void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
|
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
Record.push_back(E->getIdentKind());
|
|
|
|
Code = serialization::EXPR_SOURCE_LOC;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getAmpAmpLoc());
|
|
|
|
Record.AddSourceLocation(E->getLabelLoc());
|
|
|
|
Record.AddDeclRef(E->getLabel());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_ADDR_LABEL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubStmt());
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_STMT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getCond());
|
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2013-07-20 08:40:58 +08:00
|
|
|
Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CHOOSE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getTokenLocation());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_GNU_NULL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSubExprs());
|
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getExpr(I));
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_SHUFFLE_VECTOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2013-09-18 11:29:45 +08:00
|
|
|
void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddStmt(E->getSrcExpr());
|
2013-09-18 11:29:45 +08:00
|
|
|
Code = serialization::EXPR_CONVERT_VECTOR;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getBlockDecl());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_BLOCK;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
|
|
|
|
VisitExpr(E);
|
2019-01-26 22:15:10 +08:00
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
Record.push_back(E->getNumAssocs());
|
2019-01-26 21:58:15 +08:00
|
|
|
Record.push_back(E->ResultIndex);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getGenericLoc());
|
|
|
|
Record.AddSourceLocation(E->getDefaultLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2019-01-26 22:15:10 +08:00
|
|
|
|
|
|
|
Stmt **Stmts = E->getTrailingObjects<Stmt *>();
|
|
|
|
// Add 1 to account for the controlling expression which is the first
|
|
|
|
// expression in the trailing array of Stmt *. This is not needed for
|
|
|
|
// the trailing array of TypeSourceInfo *.
|
|
|
|
for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
|
|
|
|
Record.AddStmt(Stmts[I]);
|
|
|
|
|
|
|
|
TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
|
|
|
|
for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
|
|
|
|
Record.AddTypeSourceInfo(TSIs[I]);
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
Code = serialization::EXPR_GENERIC_SELECTION;
|
|
|
|
}
|
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSemanticExprs());
|
|
|
|
|
|
|
|
// Push the result index. Currently, this needs to exactly match
|
|
|
|
// the encoding used internally for ResultIndex.
|
|
|
|
unsigned result = E->getResultExprIndex();
|
|
|
|
result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
|
|
|
|
Record.push_back(result);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSyntacticForm());
|
2011-11-06 17:01:30 +08:00
|
|
|
for (PseudoObjectExpr::semantics_iterator
|
|
|
|
i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(*i);
|
2011-11-06 17:01:30 +08:00
|
|
|
}
|
2011-11-15 14:20:27 +08:00
|
|
|
Code = serialization::EXPR_PSEUDO_OBJECT;
|
2011-11-06 17:01:30 +08:00
|
|
|
}
|
|
|
|
|
2011-10-11 10:20:01 +08:00
|
|
|
void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getOp());
|
2012-04-11 06:49:28 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExprs()[I]);
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2011-11-15 14:20:27 +08:00
|
|
|
Code = serialization::EXPR_ATOMIC;
|
2011-10-11 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Objective-C Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getString());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_STRING_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-04-19 08:25:12 +08:00
|
|
|
void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
2012-03-07 04:05:56 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Record.AddDeclRef(E->getBoxingMethod());
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-04-19 08:25:12 +08:00
|
|
|
Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
|
2012-03-07 04:05:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumElements());
|
|
|
|
for (unsigned i = 0; i < E->getNumElements(); i++)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getElement(i));
|
|
|
|
Record.AddDeclRef(E->getArrayWithObjectsMethod());
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-03-07 04:05:56 +08:00
|
|
|
Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumElements());
|
|
|
|
Record.push_back(E->HasPackExpansions);
|
|
|
|
for (unsigned i = 0; i < E->getNumElements(); i++) {
|
|
|
|
ObjCDictionaryElement Element = E->getKeyValueElement(i);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(Element.Key);
|
|
|
|
Record.AddStmt(Element.Value);
|
2012-03-07 04:05:56 +08:00
|
|
|
if (E->HasPackExpansions) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(Element.EllipsisLoc);
|
2012-03-07 04:05:56 +08:00
|
|
|
unsigned NumExpansions = 0;
|
|
|
|
if (Element.NumExpansions)
|
|
|
|
NumExpansions = *Element.NumExpansions + 1;
|
|
|
|
Record.push_back(NumExpansions);
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getDictWithObjectsMethod());
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-03-07 04:05:56 +08:00
|
|
|
Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_ENCODE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSelectorRef(E->getSelector());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getProtocol());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
|
|
Record.AddSourceLocation(E->ProtoLoc);
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getDecl());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddSourceLocation(E->getOpLoc());
|
|
|
|
Record.AddStmt(E->getBase());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Record.push_back(E->isFreeIvar());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2012-03-30 08:19:18 +08:00
|
|
|
Record.push_back(E->SetterAndMethodRefFlags.getInt());
|
2010-12-02 09:19:52 +08:00
|
|
|
Record.push_back(E->isImplicitProperty());
|
|
|
|
if (E->isImplicitProperty()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getImplicitPropertyGetter());
|
|
|
|
Record.AddDeclRef(E->getImplicitPropertySetter());
|
2010-12-02 09:19:52 +08:00
|
|
|
} else {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getExplicitProperty());
|
2010-12-02 09:19:52 +08:00
|
|
|
}
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddSourceLocation(E->getReceiverLocation());
|
2010-12-02 09:19:52 +08:00
|
|
|
if (E->isObjectReceiver()) {
|
|
|
|
Record.push_back(0);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
2010-12-02 09:19:52 +08:00
|
|
|
} else if (E->isSuperReceiver()) {
|
|
|
|
Record.push_back(1);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeRef(E->getSuperReceiverType());
|
2010-12-02 09:19:52 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(2);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getClassReceiver());
|
2010-12-02 09:19:52 +08:00
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getRBracket());
|
|
|
|
Record.AddStmt(E->getBaseExpr());
|
|
|
|
Record.AddStmt(E->getKeyExpr());
|
|
|
|
Record.AddDeclRef(E->getAtIndexMethodDecl());
|
|
|
|
Record.AddDeclRef(E->setAtIndexMethodDecl());
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumArgs());
|
2011-10-03 14:36:51 +08:00
|
|
|
Record.push_back(E->getNumStoredSelLocs());
|
|
|
|
Record.push_back(E->SelLocsKind);
|
2011-06-16 07:02:42 +08:00
|
|
|
Record.push_back(E->isDelegateInitCall());
|
2012-01-12 10:34:39 +08:00
|
|
|
Record.push_back(E->IsImplicit);
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
|
|
|
|
switch (E->getReceiverKind()) {
|
|
|
|
case ObjCMessageExpr::Instance:
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getInstanceReceiver());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::Class:
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getClassReceiverTypeInfo());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::SuperClass:
|
|
|
|
case ObjCMessageExpr::SuperInstance:
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeRef(E->getSuperType());
|
|
|
|
Record.AddSourceLocation(E->getSuperLoc());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (E->getMethodDecl()) {
|
|
|
|
Record.push_back(1);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getMethodDecl());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(0);
|
2018-07-31 03:24:48 +08:00
|
|
|
Record.AddSelectorRef(E->getSelector());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLeftLoc());
|
|
|
|
Record.AddSourceLocation(E->getRightLoc());
|
2009-04-27 14:20:01 +08:00
|
|
|
|
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
|
|
Arg != ArgEnd; ++Arg)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(*Arg);
|
2011-10-03 14:36:51 +08:00
|
|
|
|
|
|
|
SourceLocation *Locs = E->getStoredSelLocs();
|
|
|
|
for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(Locs[i]);
|
2011-10-03 14:36:51 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getElement());
|
|
|
|
Record.AddStmt(S->getCollection());
|
|
|
|
Record.AddStmt(S->getBody());
|
|
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_FOR_COLLECTION;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
2019-03-13 05:31:00 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCatchBody());
|
|
|
|
Record.AddDeclRef(S->getCatchParamDecl());
|
|
|
|
Record.AddSourceLocation(S->getAtCatchLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_CATCH;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
2019-03-13 05:31:00 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getFinallyBody());
|
|
|
|
Record.AddSourceLocation(S->getAtFinallyLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_FINALLY;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
|
2019-03-13 05:31:00 +08:00
|
|
|
VisitStmt(S); // FIXME: no test coverage.
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getSubStmt());
|
|
|
|
Record.AddSourceLocation(S->getAtLoc());
|
2011-06-16 07:02:42 +08:00
|
|
|
Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
|
2019-03-13 05:31:00 +08:00
|
|
|
VisitStmt(S);
|
2010-04-24 06:50:49 +08:00
|
|
|
Record.push_back(S->getNumCatchStmts());
|
2014-05-22 13:54:18 +08:00
|
|
|
Record.push_back(S->getFinallyStmt() != nullptr);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getTryBody());
|
2010-04-24 06:50:49 +08:00
|
|
|
for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getCatchStmt(I));
|
2010-04-24 06:50:49 +08:00
|
|
|
if (S->getFinallyStmt())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getFinallyStmt());
|
|
|
|
Record.AddSourceLocation(S->getAtTryLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_AT_TRY;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
|
2019-03-13 05:31:00 +08:00
|
|
|
VisitStmt(S); // FIXME: no test coverage.
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getSynchExpr());
|
|
|
|
Record.AddStmt(S->getSynchBody());
|
|
|
|
Record.AddSourceLocation(S->getAtSynchronizedLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
|
2019-03-13 05:31:00 +08:00
|
|
|
VisitStmt(S); // FIXME: no test coverage.
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getThrowExpr());
|
|
|
|
Record.AddSourceLocation(S->getThrowLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_AT_THROW;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2012-03-07 04:05:56 +08:00
|
|
|
Code = serialization::EXPR_OBJC_BOOL_LITERAL;
|
|
|
|
}
|
|
|
|
|
2016-07-16 08:35:23 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddVersionTuple(E->getVersion());
|
|
|
|
Code = serialization::EXPR_OBJC_AVAILABILITY_CHECK;
|
|
|
|
}
|
|
|
|
|
2009-07-14 11:19:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
|
2010-07-23 00:03:56 +08:00
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getCatchLoc());
|
|
|
|
Record.AddDeclRef(S->getExceptionDecl());
|
|
|
|
Record.AddStmt(S->getHandlerBlock());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CXX_CATCH;
|
2010-07-23 00:03:56 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
|
2010-07-23 00:03:56 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getNumHandlers());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getTryLoc());
|
|
|
|
Record.AddStmt(S->getTryBlock());
|
2010-07-23 00:03:56 +08:00
|
|
|
for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getHandler(i));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CXX_TRY;
|
2010-07-23 00:03:56 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 06:09:26 +08:00
|
|
|
void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
|
|
Record.AddSourceLocation(S->getCoawaitLoc());
|
|
|
|
Record.AddSourceLocation(S->getColonLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2018-09-29 02:44:09 +08:00
|
|
|
Record.AddStmt(S->getInit());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(S->getRangeStmt());
|
|
|
|
Record.AddStmt(S->getBeginStmt());
|
|
|
|
Record.AddStmt(S->getEndStmt());
|
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getInc());
|
|
|
|
Record.AddStmt(S->getLoopVarStmt());
|
|
|
|
Record.AddStmt(S->getBody());
|
2011-04-15 06:09:26 +08:00
|
|
|
Code = serialization::STMT_CXX_FOR_RANGE;
|
|
|
|
}
|
|
|
|
|
2011-10-25 09:33:02 +08:00
|
|
|
void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
2011-10-25 09:33:02 +08:00
|
|
|
Record.push_back(S->isIfExists());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
|
|
|
|
Record.AddDeclarationNameInfo(S->getNameInfo());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
2011-10-25 09:33:02 +08:00
|
|
|
Code = serialization::STMT_MS_DEPENDENT_EXISTS;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
|
2009-07-14 11:19:21 +08:00
|
|
|
VisitCallExpr(E);
|
|
|
|
Record.push_back(E->getOperator());
|
2017-03-28 03:17:25 +08:00
|
|
|
Record.push_back(E->getFPFeatures().getInt());
|
2018-12-22 00:51:57 +08:00
|
|
|
Record.AddSourceRange(E->Range);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_OPERATOR_CALL;
|
2009-07-14 11:19:21 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
2010-05-09 13:36:05 +08:00
|
|
|
VisitCallExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_MEMBER_CALL;
|
2010-05-09 13:36:05 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
2009-09-10 07:08:42 +08:00
|
|
|
VisitExpr(E);
|
2018-12-22 22:39:30 +08:00
|
|
|
|
2010-06-24 16:57:09 +08:00
|
|
|
Record.push_back(E->getNumArgs());
|
2009-09-10 07:08:42 +08:00
|
|
|
Record.push_back(E->isElidable());
|
2011-10-05 15:56:41 +08:00
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
2012-12-19 09:39:02 +08:00
|
|
|
Record.push_back(E->isListInitialization());
|
2014-07-17 13:12:35 +08:00
|
|
|
Record.push_back(E->isStdInitListInitialization());
|
2009-12-17 02:50:27 +08:00
|
|
|
Record.push_back(E->requiresZeroInitialization());
|
2010-05-15 08:13:29 +08:00
|
|
|
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
|
2018-12-22 22:39:30 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddDeclRef(E->getConstructor());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getParenOrBraceRange());
|
2018-12-22 22:39:30 +08:00
|
|
|
|
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
|
|
Record.AddStmt(E->getArg(I));
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_CONSTRUCT;
|
2009-09-10 07:08:42 +08:00
|
|
|
}
|
|
|
|
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddDeclRef(E->getConstructor());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.push_back(E->constructsVBase());
|
|
|
|
Record.push_back(E->inheritedFromVBase());
|
|
|
|
Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
|
2010-07-10 19:46:15 +08:00
|
|
|
VisitCXXConstructExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
|
2010-07-10 19:46:15 +08:00
|
|
|
}
|
|
|
|
|
2012-02-07 18:09:13 +08:00
|
|
|
void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
|
|
|
|
VisitExpr(E);
|
2012-02-15 01:54:36 +08:00
|
|
|
Record.push_back(E->NumCaptures);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->IntroducerRange);
|
2012-02-15 01:54:36 +08:00
|
|
|
Record.push_back(E->CaptureDefault); // FIXME: stable encoding
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->CaptureDefaultLoc);
|
2012-02-15 01:54:36 +08:00
|
|
|
Record.push_back(E->ExplicitParams);
|
|
|
|
Record.push_back(E->ExplicitResultType);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->ClosingBrace);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-02-15 01:54:36 +08:00
|
|
|
// Add capture initializers.
|
|
|
|
for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
|
|
|
|
CEnd = E->capture_init_end();
|
|
|
|
C != CEnd; ++C) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(*C);
|
2012-02-15 01:54:36 +08:00
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-02-15 01:54:36 +08:00
|
|
|
Code = serialization::EXPR_LAMBDA;
|
2012-02-07 18:09:13 +08:00
|
|
|
}
|
|
|
|
|
2013-06-13 06:31:48 +08:00
|
|
|
void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2013-06-13 06:31:48 +08:00
|
|
|
Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
|
|
|
|
Record.AddSourceRange(E->getAngleBrackets());
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_STATIC_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DYNAMIC_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_REINTERPRET_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_CONST_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2019-07-03 02:28:13 +08:00
|
|
|
void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) {
|
|
|
|
VisitExplicitCastExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
}
|
|
|
|
|
2012-03-07 16:35:16 +08:00
|
|
|
void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
|
|
|
|
VisitCallExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->UDSuffixLoc);
|
2012-03-07 16:35:16 +08:00
|
|
|
Code = serialization::EXPR_USER_DEFINED_LITERAL;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
2010-02-07 14:32:43 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_BOOL_LITERAL;
|
2010-02-07 14:32:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
|
2010-02-07 14:32:43 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
|
2010-02-07 14:32:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
2010-05-09 14:03:39 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2010-05-09 14:03:39 +08:00
|
|
|
if (E->isTypeOperand()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_TYPEID_TYPE;
|
2010-05-09 14:03:39 +08:00
|
|
|
} else {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getExprOperand());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_TYPEID_EXPR;
|
2010-05-09 14:03:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
|
2010-05-09 14:15:05 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-05-09 14:15:05 +08:00
|
|
|
Record.push_back(E->isImplicit());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_THIS;
|
2010-05-09 14:15:05 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
|
2010-05-09 14:40:08 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getThrowLoc());
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2011-07-07 06:04:06 +08:00
|
|
|
Record.push_back(E->isThrownVariableInScope());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_THROW;
|
2010-05-09 14:15:05 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
2010-05-09 14:40:08 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getParam());
|
Implement __builtin_LINE() et. al. to support source location capture.
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
2019-05-17 05:04:15 +08:00
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getUsedLocation());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_ARG;
|
2010-05-09 14:40:08 +08:00
|
|
|
}
|
|
|
|
|
2013-04-21 06:23:05 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getField());
|
Implement __builtin_LINE() et. al. to support source location capture.
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
2019-05-17 05:04:15 +08:00
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getExprLoc());
|
2013-04-21 06:23:05 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_INIT;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
2010-05-10 08:25:06 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddCXXTemporary(E->getTemporary());
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_BIND_TEMPORARY;
|
2010-05-10 08:25:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
2010-05-10 09:22:27 +08:00
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
|
2010-05-10 09:22:27 +08:00
|
|
|
VisitExpr(E);
|
2019-01-07 23:04:45 +08:00
|
|
|
|
2012-02-16 19:35:52 +08:00
|
|
|
Record.push_back(E->isArray());
|
2019-01-07 23:04:45 +08:00
|
|
|
Record.push_back(E->hasInitializer());
|
|
|
|
Record.push_back(E->getNumPlacementArgs());
|
|
|
|
Record.push_back(E->isParenTypeId());
|
|
|
|
|
|
|
|
Record.push_back(E->isGlobalNew());
|
2016-10-11 02:54:32 +08:00
|
|
|
Record.push_back(E->passAlignment());
|
2012-02-16 20:22:20 +08:00
|
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
2019-01-07 23:04:45 +08:00
|
|
|
Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getOperatorNew());
|
|
|
|
Record.AddDeclRef(E->getOperatorDelete());
|
|
|
|
Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
|
2019-01-07 23:04:45 +08:00
|
|
|
if (E->isParenTypeId())
|
|
|
|
Record.AddSourceRange(E->getTypeIdParens());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddSourceRange(E->getDirectInitRange());
|
2019-01-07 23:04:45 +08:00
|
|
|
|
|
|
|
for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
|
|
|
|
I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(*I);
|
2012-02-16 20:22:20 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_NEW;
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
2010-06-23 01:07:59 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isGlobalDelete());
|
|
|
|
Record.push_back(E->isArrayForm());
|
2010-09-14 04:15:54 +08:00
|
|
|
Record.push_back(E->isArrayFormAsWritten());
|
2011-01-27 17:37:56 +08:00
|
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getOperatorDelete());
|
|
|
|
Record.AddStmt(E->getArgument());
|
2018-12-03 20:32:32 +08:00
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DELETE;
|
2010-06-23 01:07:59 +08:00
|
|
|
}
|
2010-05-10 09:22:27 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
2010-06-28 17:32:03 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
2010-06-28 17:32:03 +08:00
|
|
|
Record.push_back(E->isArrow());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getScopeTypeInfo());
|
|
|
|
Record.AddSourceLocation(E->getColonColonLoc());
|
|
|
|
Record.AddSourceLocation(E->getTildeLoc());
|
2010-06-28 17:32:03 +08:00
|
|
|
|
|
|
|
// PseudoDestructorTypeStorage.
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
|
2010-06-28 17:32:03 +08:00
|
|
|
if (E->getDestroyedTypeIdentifier())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getDestroyedTypeLoc());
|
2010-06-28 17:32:03 +08:00
|
|
|
else
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());
|
2010-06-28 17:32:03 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
|
2010-06-28 17:32:03 +08:00
|
|
|
}
|
|
|
|
|
2010-12-06 16:20:24 +08:00
|
|
|
void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
2010-05-10 08:25:06 +08:00
|
|
|
VisitExpr(E);
|
2011-11-10 13:35:25 +08:00
|
|
|
Record.push_back(E->getNumObjects());
|
|
|
|
for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getObject(i));
|
2016-06-22 04:29:17 +08:00
|
|
|
|
|
|
|
Record.push_back(E->cleanupsHaveSideEffects());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-12-06 16:20:24 +08:00
|
|
|
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
2010-05-10 08:25:06 +08:00
|
|
|
}
|
|
|
|
|
2019-01-08 22:17:00 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
|
|
|
|
CXXDependentScopeMemberExpr *E) {
|
2010-06-24 16:57:31 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
2019-01-08 22:17:00 +08:00
|
|
|
// Don't emit anything here (or if you do you will have to update
|
|
|
|
// the corresponding deserialization function).
|
|
|
|
|
|
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
|
|
|
Record.push_back(E->getNumTemplateArgs());
|
|
|
|
Record.push_back(E->hasFirstQualifierFoundInScope());
|
2010-06-24 16:57:31 +08:00
|
|
|
|
2019-01-08 22:17:00 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2015-12-30 02:15:14 +08:00
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
|
|
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
|
|
|
AddTemplateKWAndArgsInfo(ArgInfo,
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
2012-01-27 17:46:47 +08:00
|
|
|
|
2019-01-08 22:17:00 +08:00
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.AddTypeRef(E->getBaseType());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
2010-06-24 16:57:31 +08:00
|
|
|
if (!E->isImplicitAccess())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
2010-06-24 16:57:31 +08:00
|
|
|
else
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(nullptr);
|
2019-01-08 22:17:00 +08:00
|
|
|
|
|
|
|
if (E->hasFirstQualifierFoundInScope())
|
|
|
|
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclarationNameInfo(E->MemberNameInfo);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
|
|
|
|
2010-06-28 17:31:56 +08:00
|
|
|
void
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
|
2010-06-28 17:31:56 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
2011-02-04 20:01:24 +08:00
|
|
|
// emitted first.
|
2012-01-27 17:46:47 +08:00
|
|
|
|
2019-01-07 22:27:04 +08:00
|
|
|
Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
|
|
|
|
if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
|
2015-12-30 02:15:14 +08:00
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
|
|
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
|
|
|
Record.push_back(ArgInfo.NumTemplateArgs);
|
|
|
|
AddTemplateKWAndArgsInfo(ArgInfo,
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
2010-06-28 17:31:56 +08:00
|
|
|
}
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
Record.AddDeclarationNameInfo(E->NameInfo);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
|
2010-06-28 17:31:56 +08:00
|
|
|
}
|
|
|
|
|
2010-06-24 16:57:31 +08:00
|
|
|
void
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
|
2010-06-24 16:57:31 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->arg_size());
|
|
|
|
for (CXXUnresolvedConstructExpr::arg_iterator
|
|
|
|
ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(*ArgI);
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
2010-05-09 14:15:05 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
|
2010-06-25 17:03:26 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
2019-01-09 23:43:19 +08:00
|
|
|
Record.push_back(E->getNumDecls());
|
|
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2015-12-30 02:15:14 +08:00
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
|
|
*E->getTrailingASTTemplateKWAndArgsInfo();
|
|
|
|
Record.push_back(ArgInfo.NumTemplateArgs);
|
|
|
|
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2019-01-09 23:43:19 +08:00
|
|
|
for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
|
|
|
|
OvE = E->decls_end();
|
|
|
|
OvI != OvE; ++OvI) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(OvI.getDecl());
|
2010-06-25 17:03:26 +08:00
|
|
|
Record.push_back(OvI.getAccess());
|
|
|
|
}
|
|
|
|
|
2019-01-09 23:43:19 +08:00
|
|
|
Record.AddDeclarationNameInfo(E->getNameInfo());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
|
2010-06-25 17:03:26 +08:00
|
|
|
VisitOverloadExpr(E);
|
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Record.push_back(E->hasUnresolvedUsing());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
|
|
|
|
Record.AddTypeRef(E->getBaseType());
|
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
|
2010-06-25 17:03:34 +08:00
|
|
|
VisitOverloadExpr(E);
|
|
|
|
Record.push_back(E->requiresADL());
|
|
|
|
Record.push_back(E->isOverloaded());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getNamingClass());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
|
2010-06-25 17:03:34 +08:00
|
|
|
}
|
|
|
|
|
2012-02-24 15:38:34 +08:00
|
|
|
void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->TypeTraitExprBits.NumArgs);
|
|
|
|
Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
|
|
|
|
Record.push_back(E->TypeTraitExprBits.Value);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-02-24 15:38:34 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getArg(I));
|
2012-02-24 15:38:34 +08:00
|
|
|
Code = serialization::EXPR_TYPE_TRAIT;
|
|
|
|
}
|
|
|
|
|
2011-04-28 08:16:57 +08:00
|
|
|
void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getTrait());
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
|
2016-09-28 18:16:56 +08:00
|
|
|
Record.AddStmt(E->getDimensionExpression());
|
2011-04-28 08:16:57 +08:00
|
|
|
Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
|
|
|
|
}
|
|
|
|
|
2011-04-25 14:54:41 +08:00
|
|
|
void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getTrait());
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddStmt(E->getQueriedExpression());
|
2011-04-25 14:54:41 +08:00
|
|
|
Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
|
|
|
|
}
|
|
|
|
|
2010-09-11 04:55:54 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddStmt(E->getOperand());
|
2010-09-11 04:55:54 +08:00
|
|
|
Code = serialization::EXPR_CXX_NOEXCEPT;
|
|
|
|
}
|
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getEllipsisLoc());
|
2011-01-15 05:20:45 +08:00
|
|
|
Record.push_back(E->NumExpansions);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getPattern());
|
2011-01-04 01:17:50 +08:00
|
|
|
Code = serialization::EXPR_PACK_EXPANSION;
|
|
|
|
}
|
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
2015-09-24 05:41:42 +08:00
|
|
|
Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
|
|
|
|
: 0);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->OperatorLoc);
|
|
|
|
Record.AddSourceLocation(E->PackLoc);
|
|
|
|
Record.AddSourceLocation(E->RParenLoc);
|
|
|
|
Record.AddDeclRef(E->Pack);
|
2015-09-24 05:41:42 +08:00
|
|
|
if (E->isPartiallySubstituted()) {
|
|
|
|
for (const auto &TA : E->getPartialArguments())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTemplateArgument(TA);
|
2015-09-24 05:41:42 +08:00
|
|
|
} else if (!E->isValueDependent()) {
|
|
|
|
Record.push_back(E->getPackLength());
|
|
|
|
}
|
2011-01-05 01:33:58 +08:00
|
|
|
Code = serialization::EXPR_SIZEOF_PACK;
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
|
|
|
|
SubstNonTypeTemplateParmExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getParameter());
|
|
|
|
Record.AddSourceLocation(E->getNameLoc());
|
|
|
|
Record.AddStmt(E->getReplacement());
|
2011-07-15 15:00:14 +08:00
|
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
|
|
|
|
}
|
|
|
|
|
2011-01-15 09:15:58 +08:00
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
|
|
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getParameterPack());
|
|
|
|
Record.AddTemplateArgument(E->getArgumentPack());
|
|
|
|
Record.AddSourceLocation(E->getParameterPackLocation());
|
2011-01-15 09:15:58 +08:00
|
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
|
|
|
|
}
|
|
|
|
|
2012-09-12 08:56:43 +08:00
|
|
|
void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumExpansions());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(E->getParameterPack());
|
|
|
|
Record.AddSourceLocation(E->getParameterPackLocation());
|
2012-09-12 08:56:43 +08:00
|
|
|
for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
|
|
|
|
I != End; ++I)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclRef(*I);
|
2012-09-12 08:56:43 +08:00
|
|
|
Code = serialization::EXPR_FUNCTION_PARM_PACK;
|
|
|
|
}
|
|
|
|
|
2011-06-22 01:03:29 +08:00
|
|
|
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getTemporary());
|
|
|
|
Record.AddDeclRef(E->getExtendingDecl());
|
2014-05-02 01:50:17 +08:00
|
|
|
Record.push_back(E->getManglingNumber());
|
2011-06-22 01:03:29 +08:00
|
|
|
Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
|
|
|
|
}
|
|
|
|
|
2014-11-08 13:07:16 +08:00
|
|
|
void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->LParenLoc);
|
|
|
|
Record.AddSourceLocation(E->EllipsisLoc);
|
|
|
|
Record.AddSourceLocation(E->RParenLoc);
|
2019-05-13 16:31:14 +08:00
|
|
|
Record.push_back(E->NumExpansions);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->SubExprs[0]);
|
|
|
|
Record.AddStmt(E->SubExprs[1]);
|
2014-11-08 13:07:16 +08:00
|
|
|
Record.push_back(E->Opcode);
|
|
|
|
Code = serialization::EXPR_CXX_FOLD;
|
|
|
|
}
|
|
|
|
|
2010-11-16 07:31:06 +08:00
|
|
|
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getSourceExpr());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2018-03-20 09:47:58 +08:00
|
|
|
Record.push_back(E->isUnique());
|
2010-11-16 07:31:06 +08:00
|
|
|
Code = serialization::EXPR_OPAQUE_VALUE;
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:07:20 +08:00
|
|
|
void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
// TODO: Figure out sane writer behavior for a TypoExpr, if necessary
|
2016-01-30 16:03:54 +08:00
|
|
|
llvm_unreachable("Cannot write TypoExpr nodes");
|
2014-10-28 02:07:20 +08:00
|
|
|
}
|
|
|
|
|
2011-02-10 05:07:24 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CUDA Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
|
|
|
VisitCallExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getConfig());
|
2011-02-10 05:07:24 +08:00
|
|
|
Code = serialization::EXPR_CUDA_KERNEL_CALL;
|
|
|
|
}
|
|
|
|
|
2011-06-04 08:47:47 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenCL Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddStmt(E->getSrcExpr());
|
2011-06-04 08:47:47 +08:00
|
|
|
Code = serialization::EXPR_ASTYPE;
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Microsoft Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-04-16 15:28:30 +08:00
|
|
|
void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isArrow());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBaseExpr());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
Record.AddSourceLocation(E->getMemberLoc());
|
|
|
|
Record.AddDeclRef(E->getPropertyDecl());
|
2013-04-16 15:28:30 +08:00
|
|
|
Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
|
|
|
|
}
|
|
|
|
|
2015-11-25 20:01:00 +08:00
|
|
|
void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getIdx());
|
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2015-11-25 20:01:00 +08:00
|
|
|
Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddString(E->getUuidStr());
|
2011-07-15 15:00:14 +08:00
|
|
|
if (E->isTypeOperand()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
|
2011-07-15 15:00:14 +08:00
|
|
|
Code = serialization::EXPR_CXX_UUIDOF_TYPE;
|
|
|
|
} else {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getExprOperand());
|
2011-07-15 15:00:14 +08:00
|
|
|
Code = serialization::EXPR_CXX_UUIDOF_EXPR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getExceptLoc());
|
|
|
|
Record.AddStmt(S->getFilterExpr());
|
|
|
|
Record.AddStmt(S->getBlock());
|
2011-07-15 15:00:14 +08:00
|
|
|
Code = serialization::STMT_SEH_EXCEPT;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getFinallyLoc());
|
|
|
|
Record.AddStmt(S->getBlock());
|
2011-07-15 15:00:14 +08:00
|
|
|
Code = serialization::STMT_SEH_FINALLY;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getIsCXXTry());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getTryLoc());
|
|
|
|
Record.AddStmt(S->getTryBlock());
|
|
|
|
Record.AddStmt(S->getHandler());
|
2011-07-15 15:00:14 +08:00
|
|
|
Code = serialization::STMT_SEH_TRY;
|
|
|
|
}
|
|
|
|
|
2014-07-07 08:12:30 +08:00
|
|
|
void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(S->getLeaveLoc());
|
2014-07-07 08:12:30 +08:00
|
|
|
Code = serialization::STMT_SEH_LEAVE;
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenMP Directives.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
|
2018-08-10 05:08:08 +08:00
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
2018-08-10 05:09:38 +08:00
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
2016-04-07 01:06:00 +08:00
|
|
|
OMPClauseWriter ClauseWriter(Record);
|
2013-07-19 11:13:43 +08:00
|
|
|
for (unsigned i = 0; i < E->getNumClauses(); ++i) {
|
|
|
|
ClauseWriter.writeClause(E->getClause(i));
|
|
|
|
}
|
2014-07-18 15:47:19 +08:00
|
|
|
if (E->hasAssociatedStmt())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getAssociatedStmt());
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:27:13 +08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
|
2014-02-27 16:29:12 +08:00
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
2014-08-19 19:27:13 +08:00
|
|
|
Record.push_back(D->getCollapsedNumber());
|
2013-07-19 11:13:43 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getIterationVariable());
|
|
|
|
Record.AddStmt(D->getLastIteration());
|
|
|
|
Record.AddStmt(D->getCalcLastIteration());
|
|
|
|
Record.AddStmt(D->getPreCond());
|
|
|
|
Record.AddStmt(D->getCond());
|
|
|
|
Record.AddStmt(D->getInit());
|
|
|
|
Record.AddStmt(D->getInc());
|
|
|
|
Record.AddStmt(D->getPreInits());
|
2016-02-16 19:18:12 +08:00
|
|
|
if (isOpenMPWorksharingDirective(D->getDirectiveKind()) ||
|
2016-03-08 00:04:49 +08:00
|
|
|
isOpenMPTaskLoopDirective(D->getDirectiveKind()) ||
|
|
|
|
isOpenMPDistributeDirective(D->getDirectiveKind())) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getIsLastIterVariable());
|
|
|
|
Record.AddStmt(D->getLowerBoundVariable());
|
|
|
|
Record.AddStmt(D->getUpperBoundVariable());
|
|
|
|
Record.AddStmt(D->getStrideVariable());
|
|
|
|
Record.AddStmt(D->getEnsureUpperBound());
|
|
|
|
Record.AddStmt(D->getNextLowerBound());
|
|
|
|
Record.AddStmt(D->getNextUpperBound());
|
2016-05-25 20:36:08 +08:00
|
|
|
Record.AddStmt(D->getNumIterations());
|
2014-12-15 15:07:06 +08:00
|
|
|
}
|
2016-06-27 22:55:37 +08:00
|
|
|
if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) {
|
|
|
|
Record.AddStmt(D->getPrevLowerBoundVariable());
|
|
|
|
Record.AddStmt(D->getPrevUpperBoundVariable());
|
2017-02-18 05:29:13 +08:00
|
|
|
Record.AddStmt(D->getDistInc());
|
|
|
|
Record.AddStmt(D->getPrevEnsureUpperBound());
|
2017-04-20 08:39:39 +08:00
|
|
|
Record.AddStmt(D->getCombinedLowerBoundVariable());
|
|
|
|
Record.AddStmt(D->getCombinedUpperBoundVariable());
|
|
|
|
Record.AddStmt(D->getCombinedEnsureUpperBound());
|
|
|
|
Record.AddStmt(D->getCombinedInit());
|
|
|
|
Record.AddStmt(D->getCombinedCond());
|
|
|
|
Record.AddStmt(D->getCombinedNextLowerBound());
|
|
|
|
Record.AddStmt(D->getCombinedNextUpperBound());
|
2018-10-29 23:45:47 +08:00
|
|
|
Record.AddStmt(D->getCombinedDistCond());
|
|
|
|
Record.AddStmt(D->getCombinedParForInDistCond());
|
2016-06-27 22:55:37 +08:00
|
|
|
}
|
2014-10-01 14:03:56 +08:00
|
|
|
for (auto I : D->counters()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2014-10-01 14:03:56 +08:00
|
|
|
}
|
2015-08-06 20:30:57 +08:00
|
|
|
for (auto I : D->private_counters()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2015-08-06 20:30:57 +08:00
|
|
|
}
|
2015-08-14 20:25:37 +08:00
|
|
|
for (auto I : D->inits()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2015-08-14 20:25:37 +08:00
|
|
|
}
|
2014-10-01 14:03:56 +08:00
|
|
|
for (auto I : D->updates()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2014-10-01 14:03:56 +08:00
|
|
|
}
|
|
|
|
for (auto I : D->finals()) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2014-10-01 14:03:56 +08:00
|
|
|
}
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:27:13 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
|
2014-02-27 16:29:12 +08:00
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-08-19 19:27:13 +08:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
2014-02-27 16:29:12 +08:00
|
|
|
Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-18 12:14:57 +08:00
|
|
|
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-06-18 12:14:57 +08:00
|
|
|
Code = serialization::STMT_OMP_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-18 13:12:34 +08:00
|
|
|
void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-25 19:44:49 +08:00
|
|
|
void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-06-25 19:44:49 +08:00
|
|
|
Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-26 16:21:58 +08:00
|
|
|
void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-06-26 16:21:58 +08:00
|
|
|
Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-26 20:05:45 +08:00
|
|
|
void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-17 16:54:58 +08:00
|
|
|
void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 17:42:05 +08:00
|
|
|
void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
|
|
|
|
VisitStmt(D);
|
2015-12-15 16:19:24 +08:00
|
|
|
Record.push_back(D->getNumClauses());
|
2014-07-21 17:42:05 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddDeclarationNameInfo(D->getDirectiveName());
|
2014-07-21 17:42:05 +08:00
|
|
|
Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-07 21:01:15 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-07-07 21:01:15 +08:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-23 17:33:00 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelForSimdDirective(
|
|
|
|
OMPParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-08 16:12:03 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelSectionsDirective(
|
|
|
|
OMPParallelSectionsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-07-08 16:12:03 +08:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 19:25:16 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2015-09-15 20:52:43 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2014-07-11 19:25:16 +08:00
|
|
|
Code = serialization::STMT_OMP_TASK_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 18:10:35 +08:00
|
|
|
void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getX());
|
|
|
|
Record.AddStmt(D->getV());
|
|
|
|
Record.AddStmt(D->getExpr());
|
|
|
|
Record.AddStmt(D->getUpdateExpr());
|
2015-03-30 13:20:59 +08:00
|
|
|
Record.push_back(D->isXLHSInRHSPart() ? 1 : 0);
|
2015-04-01 11:33:17 +08:00
|
|
|
Record.push_back(D->isPostfixUpdate() ? 1 : 0);
|
2014-07-22 18:10:35 +08:00
|
|
|
Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-19 16:19:49 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-21 21:44:28 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
|
2016-01-20 03:15:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
|
|
|
|
OMPTargetEnterDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
|
2016-01-20 04:04:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTargetExitDataDirective(
|
|
|
|
OMPTargetExitDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
|
2015-07-21 21:44:28 +08:00
|
|
|
}
|
|
|
|
|
2016-01-27 02:48:41 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelDirective(
|
|
|
|
OMPTargetParallelDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-02-03 23:46:42 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelForDirective(
|
|
|
|
OMPTargetParallelForDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 15:47:19 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 17:11:51 +08:00
|
|
|
void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 18:17:07 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-06-18 20:14:09 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
|
|
|
VisitStmt(D);
|
2017-07-19 04:17:46 +08:00
|
|
|
Record.push_back(D->getNumClauses());
|
2015-06-18 20:14:09 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
2017-07-25 23:53:26 +08:00
|
|
|
Record.AddStmt(D->getReductionRef());
|
2015-06-18 20:14:09 +08:00
|
|
|
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 19:26:11 +08:00
|
|
|
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 14:45:04 +08:00
|
|
|
void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
|
|
|
VisitStmt(D);
|
2015-09-25 18:37:12 +08:00
|
|
|
Record.push_back(D->getNumClauses());
|
2014-07-22 14:45:04 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-10-09 12:18:56 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-01 14:57:41 +08:00
|
|
|
void ASTStmtWriter::VisitOMPCancellationPointDirective(
|
|
|
|
OMPCancellationPointDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Record.push_back(D->getCancelRegion());
|
|
|
|
Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-02 19:25:17 +08:00
|
|
|
void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
|
|
|
VisitStmt(D);
|
2015-09-18 16:07:34 +08:00
|
|
|
Record.push_back(D->getNumClauses());
|
2015-07-02 19:25:17 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Record.push_back(D->getCancelRegion());
|
|
|
|
Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-01 12:18:41 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-03 17:40:15 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-14 22:51:25 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-05-27 01:30:50 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-06-27 22:55:37 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
|
|
|
|
OMPDistributeParallelForDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
2017-11-23 04:19:50 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2016-06-27 22:55:37 +08:00
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-05 13:00:15 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
|
|
|
|
OMPDistributeParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-06 12:45:38 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeSimdDirective(
|
|
|
|
OMPDistributeSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-14 10:54:56 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
|
|
|
|
OMPTargetParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-21 06:57:10 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-08-05 22:37:37 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
|
|
|
|
OMPTeamsDistributeDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-10-25 20:50:55 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
|
|
|
|
OMPTeamsDistributeSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-01 07:51:03 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
|
|
|
|
OMPTeamsDistributeParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-09 11:24:30 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
|
|
|
|
OMPTeamsDistributeParallelForDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
2017-11-23 04:19:50 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2016-12-09 11:24:30 +08:00
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-17 13:48:59 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-25 12:52:54 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
|
|
|
|
OMPTargetTeamsDistributeDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-30 06:16:30 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
|
|
|
|
OMPTargetTeamsDistributeParallelForDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
2017-11-23 05:12:03 +08:00
|
|
|
Record.push_back(D->hasCancel() ? 1 : 0);
|
2016-12-30 06:16:30 +08:00
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2017-01-03 13:23:48 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
|
|
|
|
OMPTargetTeamsDistributeParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::
|
|
|
|
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2017-01-11 02:08:18 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
|
|
|
|
OMPTargetTeamsDistributeSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-08-19 07:56:21 +08:00
|
|
|
// ASTWriter Implementation
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:21 +08:00
|
|
|
unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
|
2009-04-27 14:20:01 +08:00
|
|
|
"SwitchCase recorded twice");
|
|
|
|
unsigned NextID = SwitchCaseIDs.size();
|
|
|
|
SwitchCaseIDs[S] = NextID;
|
|
|
|
return NextID;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:21 +08:00
|
|
|
unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
|
2009-04-27 14:20:01 +08:00
|
|
|
"SwitchCase hasn't been seen yet");
|
|
|
|
return SwitchCaseIDs[S];
|
|
|
|
}
|
|
|
|
|
2010-10-28 17:29:32 +08:00
|
|
|
void ASTWriter::ClearSwitchCaseIDs() {
|
|
|
|
SwitchCaseIDs.clear();
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Write the given substatement or subexpression to the
|
2009-04-27 14:20:01 +08:00
|
|
|
/// bitstream.
|
2016-04-07 04:12:34 +08:00
|
|
|
void ASTWriter::WriteSubStmt(Stmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
RecordData Record;
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter Writer(*this, Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
++NumStatements;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
if (!S) {
|
2010-08-19 07:57:32 +08:00
|
|
|
Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-10-22 07:02:28 +08:00
|
|
|
llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
|
|
|
|
if (I != SubStmtEntries.end()) {
|
|
|
|
Record.push_back(I->second);
|
|
|
|
Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
|
|
|
|
|
|
|
|
struct ParentStmtInserterRAII {
|
|
|
|
Stmt *S;
|
|
|
|
llvm::DenseSet<Stmt *> &ParentStmts;
|
|
|
|
|
|
|
|
ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
|
|
|
|
: S(S), ParentStmts(ParentStmts) {
|
|
|
|
ParentStmts.insert(S);
|
|
|
|
}
|
|
|
|
~ParentStmtInserterRAII() {
|
|
|
|
ParentStmts.erase(S);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
|
|
|
|
#endif
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.Visit(S);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-04-07 04:57:53 +08:00
|
|
|
uint64_t Offset = Writer.Emit();
|
|
|
|
SubStmtEntries[S] = Offset;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Flush all of the statements that have been added to the
|
2009-04-27 14:20:01 +08:00
|
|
|
/// queue via AddStmt().
|
2016-04-07 01:06:00 +08:00
|
|
|
void ASTRecordWriter::FlushStmts() {
|
2012-02-29 10:39:13 +08:00
|
|
|
// We expect to be the only consumer of the two temporary statement maps,
|
|
|
|
// assert that they are empty.
|
2016-04-07 01:06:00 +08:00
|
|
|
assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
|
|
|
|
assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
|
2011-10-22 07:02:28 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
2016-04-07 04:12:34 +08:00
|
|
|
Writer->WriteSubStmt(StmtsToEmit[I]);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
assert(N == StmtsToEmit.size() && "record modified while being written!");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
// Note that we are at the end of a full expression. Any
|
|
|
|
// expression records that follow this one are part of a different
|
|
|
|
// expression.
|
2016-04-07 01:06:00 +08:00
|
|
|
Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());
|
|
|
|
|
|
|
|
Writer->SubStmtEntries.clear();
|
|
|
|
Writer->ParentStmts.clear();
|
|
|
|
}
|
2011-10-22 07:02:28 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
StmtsToEmit.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTRecordWriter::FlushSubStmts() {
|
|
|
|
// For a nested statement, write out the substatements in reverse order (so
|
|
|
|
// that a simple stack machine can be used when loading), and don't emit a
|
|
|
|
// STMT_STOP after each one.
|
|
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
2016-04-07 04:12:34 +08:00
|
|
|
Writer->WriteSubStmt(StmtsToEmit[N - I - 1]);
|
2016-04-07 01:06:00 +08:00
|
|
|
assert(N == StmtsToEmit.size() && "record modified while being written!");
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
StmtsToEmit.clear();
|
|
|
|
}
|