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
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2020-04-06 23:21:43 +08:00
|
|
|
#include "clang/AST/ExprOpenMP.h"
|
2019-12-14 16:17:03 +08:00
|
|
|
#include "clang/Serialization/ASTRecordWriter.h"
|
2020-01-18 15:11:43 +08:00
|
|
|
#include "clang/Sema/DeclSpec.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) {
|
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);
|
[Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1
This patch is the Part-1 (FE Clang) implementation of HW Exception handling.
This new feature adds the support of Hardware Exception for Microsoft Windows
SEH (Structured Exception Handling).
This is the first step of this project; only X86_64 target is enabled in this patch.
Compiler options:
For clang-cl.exe, the option is -EHa, the same as MSVC.
For clang.exe, the extra option is -fasync-exceptions,
plus -triple x86_64-windows -fexceptions and -fcxx-exceptions as usual.
NOTE:: Without the -EHa or -fasync-exceptions, this patch is a NO-DIFF change.
The rules for C code:
For C-code, one way (MSVC approach) to achieve SEH -EHa semantic is to follow
three rules:
* First, no exception can move in or out of _try region., i.e., no "potential
faulty instruction can be moved across _try boundary.
* Second, the order of exceptions for instructions 'directly' under a _try
must be preserved (not applied to those in callees).
* Finally, global states (local/global/heap variables) that can be read
outside of _try region must be updated in memory (not just in register)
before the subsequent exception occurs.
The impact to C++ code:
Although SEH is a feature for C code, -EHa does have a profound effect on C++
side. When a C++ function (in the same compilation unit with option -EHa ) is
called by a SEH C function, a hardware exception occurs in C++ code can also
be handled properly by an upstream SEH _try-handler or a C++ catch(...).
As such, when that happens in the middle of an object's life scope, the dtor
must be invoked the same way as C++ Synchronous Exception during unwinding
process.
Design:
A natural way to achieve the rules above in LLVM today is to allow an EH edge
added on memory/computation instruction (previous iload/istore idea) so that
exception path is modeled in Flow graph preciously. However, tracking every
single memory instruction and potential faulty instruction can create many
Invokes, complicate flow graph and possibly result in negative performance
impact for downstream optimization and code generation. Making all
optimizations be aware of the new semantic is also substantial.
This design does not intend to model exception path at instruction level.
Instead, the proposed design tracks and reports EH state at BLOCK-level to
reduce the complexity of flow graph and minimize the performance-impact on CPP
code under -EHa option.
One key element of this design is the ability to compute State number at
block-level. Our algorithm is based on the following rationales:
A _try scope is always a SEME (Single Entry Multiple Exits) region as jumping
into a _try is not allowed. The single entry must start with a seh_try_begin()
invoke with a correct State number that is the initial state of the SEME.
Through control-flow, state number is propagated into all blocks. Side exits
marked by seh_try_end() will unwind to parent state based on existing
SEHUnwindMap[].
Note side exits can ONLY jump into parent scopes (lower state number).
Thus, when a block succeeds various states from its predecessors, the lowest
State triumphs others. If some exits flow to unreachable, propagation on those
paths terminate, not affecting remaining blocks.
For CPP code, object lifetime region is usually a SEME as SEH _try.
However there is one rare exception: jumping into a lifetime that has Dtor but
has no Ctor is warned, but allowed:
Warning: jump bypasses variable with a non-trivial destructor
In that case, the region is actually a MEME (multiple entry multiple exits).
Our solution is to inject a eha_scope_begin() invoke in the side entry block to
ensure a correct State.
Implementation:
Part-1: Clang implementation described below.
Two intrinsic are created to track CPP object scopes; eha_scope_begin() and eha_scope_end().
_scope_begin() is immediately added after ctor() is called and EHStack is pushed.
So it must be an invoke, not a call. With that it's also guaranteed an
EH-cleanup-pad is created regardless whether there exists a call in this scope.
_scope_end is added before dtor(). These two intrinsics make the computation of
Block-State possible in downstream code gen pass, even in the presence of
ctor/dtor inlining.
Two intrinsic, seh_try_begin() and seh_try_end(), are added for C-code to mark
_try boundary and to prevent from exceptions being moved across _try boundary.
All memory instructions inside a _try are considered as 'volatile' to assure
2nd and 3rd rules for C-code above. This is a little sub-optimized. But it's
acceptable as the amount of code directly under _try is very small.
Part-2 (will be in Part-2 patch): LLVM implementation described below.
For both C++ & C-code, the state of each block is computed at the same place in
BE (WinEHPreparing pass) where all other EH tables/maps are calculated.
In addition to _scope_begin & _scope_end, the computation of block state also
rely on the existing State tracking code (UnwindMap and InvokeStateMap).
For both C++ & C-code, the state of each block with potential trap instruction
is marked and reported in DAG Instruction Selection pass, the same place where
the state for -EHsc (synchronous exceptions) is done.
If the first instruction in a reported block scope can trap, a Nop is injected
before this instruction. This nop is needed to accommodate LLVM Windows EH
implementation, in which the address in IPToState table is offset by +1.
(note the purpose of that is to ensure the return address of a call is in the
same scope as the call address.
The handler for catch(...) for -EHa must handle HW exception. So it is
'adjective' flag is reset (it cannot be IsStdDotDot (0x40) that only catches
C++ exceptions).
Suppress push/popTerminate() scope (from noexcept/noTHrow) so that HW
exceptions can be passed through.
Original llvm-dev [RFC] discussions can be found in these two threads below:
https://lists.llvm.org/pipermail/llvm-dev/2020-March/140541.html
https://lists.llvm.org/pipermail/llvm-dev/2020-April/141338.html
Differential Revision: https://reviews.llvm.org/D80344/new/
2021-05-18 13:06:32 +08:00
|
|
|
Record.push_back(S->isSideEntry());
|
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;
|
|
|
|
|
|
|
|
Record.push_back(HasElse);
|
|
|
|
Record.push_back(HasVar);
|
|
|
|
Record.push_back(HasInit);
|
2021-10-05 20:02:53 +08:00
|
|
|
Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
|
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());
|
2020-08-11 07:29:33 +08:00
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
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());
|
2020-08-11 07:29:33 +08:00
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
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());
|
2020-07-10 11:19:06 +08:00
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
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
|
|
|
}
|
|
|
|
|
2020-01-18 15:11:43 +08:00
|
|
|
static void
|
|
|
|
addConstraintSatisfaction(ASTRecordWriter &Record,
|
|
|
|
const ASTConstraintSatisfaction &Satisfaction) {
|
2019-12-06 07:30:21 +08:00
|
|
|
Record.push_back(Satisfaction.IsSatisfied);
|
|
|
|
if (!Satisfaction.IsSatisfied) {
|
|
|
|
Record.push_back(Satisfaction.NumRecords);
|
|
|
|
for (const auto &DetailRecord : Satisfaction) {
|
|
|
|
Record.AddStmt(const_cast<Expr *>(DetailRecord.first));
|
|
|
|
auto *E = DetailRecord.second.dyn_cast<Expr *>();
|
|
|
|
Record.push_back(E == nullptr);
|
|
|
|
if (E)
|
|
|
|
Record.AddStmt(E);
|
|
|
|
else {
|
|
|
|
auto *Diag = DetailRecord.second.get<std::pair<SourceLocation,
|
|
|
|
StringRef> *>();
|
|
|
|
Record.AddSourceLocation(Diag->first);
|
|
|
|
Record.AddString(Diag->second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-18 15:11:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
addSubstitutionDiagnostic(
|
|
|
|
ASTRecordWriter &Record,
|
|
|
|
const concepts::Requirement::SubstitutionDiagnostic *D) {
|
|
|
|
Record.AddString(D->SubstitutedEntity);
|
|
|
|
Record.AddSourceLocation(D->DiagLoc);
|
|
|
|
Record.AddString(D->DiagMessage);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitConceptSpecializationExpr(
|
|
|
|
ConceptSpecializationExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments();
|
|
|
|
Record.push_back(TemplateArgs.size());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc());
|
|
|
|
Record.AddSourceLocation(E->getTemplateKWLoc());
|
|
|
|
Record.AddDeclarationNameInfo(E->getConceptNameInfo());
|
|
|
|
Record.AddDeclRef(E->getNamedConcept());
|
2020-03-11 04:04:11 +08:00
|
|
|
Record.AddDeclRef(E->getFoundDecl());
|
2020-01-18 15:11:43 +08:00
|
|
|
Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
|
|
|
|
for (const TemplateArgument &Arg : TemplateArgs)
|
|
|
|
Record.AddTemplateArgument(Arg);
|
|
|
|
if (!E->isValueDependent())
|
|
|
|
addConstraintSatisfaction(Record, E->getSatisfaction());
|
2019-12-06 07:30:21 +08:00
|
|
|
|
2019-10-15 23:24:26 +08:00
|
|
|
Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
|
|
|
|
}
|
|
|
|
|
2020-01-18 15:11:43 +08:00
|
|
|
void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getLocalParameters().size());
|
|
|
|
Record.push_back(E->getRequirements().size());
|
|
|
|
Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
|
|
|
|
Record.push_back(E->RequiresExprBits.IsSatisfied);
|
|
|
|
Record.AddDeclRef(E->getBody());
|
|
|
|
for (ParmVarDecl *P : E->getLocalParameters())
|
|
|
|
Record.AddDeclRef(P);
|
|
|
|
for (concepts::Requirement *R : E->getRequirements()) {
|
|
|
|
if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) {
|
|
|
|
Record.push_back(concepts::Requirement::RK_Type);
|
|
|
|
Record.push_back(TypeReq->Status);
|
|
|
|
if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure)
|
|
|
|
addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic());
|
|
|
|
else
|
|
|
|
Record.AddTypeSourceInfo(TypeReq->getType());
|
|
|
|
} else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
|
|
|
|
Record.push_back(ExprReq->getKind());
|
|
|
|
Record.push_back(ExprReq->Status);
|
|
|
|
if (ExprReq->isExprSubstitutionFailure()) {
|
|
|
|
addSubstitutionDiagnostic(Record,
|
|
|
|
ExprReq->Value.get<concepts::Requirement::SubstitutionDiagnostic *>());
|
|
|
|
} else
|
|
|
|
Record.AddStmt(ExprReq->Value.get<Expr *>());
|
|
|
|
if (ExprReq->getKind() == concepts::Requirement::RK_Compound) {
|
|
|
|
Record.AddSourceLocation(ExprReq->NoexceptLoc);
|
|
|
|
const auto &RetReq = ExprReq->getReturnTypeRequirement();
|
|
|
|
if (RetReq.isSubstitutionFailure()) {
|
|
|
|
Record.push_back(2);
|
|
|
|
addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic());
|
|
|
|
} else if (RetReq.isTypeConstraint()) {
|
|
|
|
Record.push_back(1);
|
|
|
|
Record.AddTemplateParameterList(
|
|
|
|
RetReq.getTypeConstraintTemplateParameterList());
|
|
|
|
if (ExprReq->Status >=
|
|
|
|
concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
|
|
|
|
Record.AddStmt(
|
|
|
|
ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr());
|
|
|
|
} else {
|
|
|
|
assert(RetReq.isEmpty());
|
|
|
|
Record.push_back(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
auto *NestedReq = cast<concepts::NestedRequirement>(R);
|
|
|
|
Record.push_back(concepts::Requirement::RK_Nested);
|
|
|
|
Record.push_back(NestedReq->isSubstitutionFailure());
|
|
|
|
if (NestedReq->isSubstitutionFailure()){
|
|
|
|
addSubstitutionDiagnostic(Record,
|
|
|
|
NestedReq->getSubstitutionDiagnostic());
|
|
|
|
} else {
|
|
|
|
Record.AddStmt(NestedReq->Value.get<Expr *>());
|
|
|
|
if (!NestedReq->isDependent())
|
|
|
|
addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
|
|
|
|
Code = serialization::EXPR_REQUIRES;
|
|
|
|
}
|
|
|
|
|
2019-10-15 23:24:26 +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());
|
2020-03-17 17:36:19 +08:00
|
|
|
Record.push_back(E->containsErrors());
|
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);
|
2020-06-21 20:02:48 +08:00
|
|
|
Record.push_back(E->ConstantExprBits.ResultKind);
|
|
|
|
|
|
|
|
Record.push_back(E->ConstantExprBits.APValueKind);
|
|
|
|
Record.push_back(E->ConstantExprBits.IsUnsigned);
|
|
|
|
Record.push_back(E->ConstantExprBits.BitWidth);
|
|
|
|
// HasCleanup not serialized since we can just query the APValue.
|
|
|
|
Record.push_back(E->ConstantExprBits.IsImmediateInvocation);
|
|
|
|
|
[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
|
|
|
switch (E->ConstantExprBits.ResultKind) {
|
2020-06-21 20:02:48 +08:00
|
|
|
case ConstantExpr::RSK_None:
|
|
|
|
break;
|
[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
|
|
|
case ConstantExpr::RSK_Int64:
|
|
|
|
Record.push_back(E->Int64Result());
|
|
|
|
break;
|
|
|
|
case ConstantExpr::RSK_APValue:
|
|
|
|
Record.AddAPValue(E->APValueResult());
|
2020-06-21 20:02:48 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("unexpected ResultKind!");
|
[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
|
|
|
}
|
2020-06-21 20:02:48 +08:00
|
|
|
|
2018-10-31 11:48:47 +08:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Code = serialization::EXPR_CONSTANT;
|
|
|
|
}
|
|
|
|
|
2021-04-23 23:22:35 +08:00
|
|
|
void ASTStmtWriter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddSourceLocation(E->getLParenLocation());
|
|
|
|
Record.AddSourceLocation(E->getRParenLocation());
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
|
|
|
|
Code = serialization::EXPR_SYCL_UNIQUE_STABLE_NAME;
|
|
|
|
}
|
|
|
|
|
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());
|
2020-04-08 03:46:08 +08:00
|
|
|
Record.push_back(E->getScale());
|
2018-06-21 01:19:40 +08:00
|
|
|
Record.AddAPInt(E->getValue());
|
2020-04-08 03:46:08 +08:00
|
|
|
Code = serialization::EXPR_FIXEDPOINT_LITERAL;
|
2018-06-21 01:19:40 +08:00
|
|
|
}
|
|
|
|
|
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);
|
2020-05-02 01:32:06 +08:00
|
|
|
bool HasFPFeatures = E->hasStoredFPFeatures();
|
|
|
|
// Write this first for easy access when deserializing, as they affect the
|
|
|
|
// size of the UnaryOperator.
|
|
|
|
Record.push_back(HasFPFeatures);
|
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());
|
2020-05-02 01:32:06 +08:00
|
|
|
if (HasFPFeatures)
|
|
|
|
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
|
2018-04-16 16:31:08 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-02 02:42:03 +08:00
|
|
|
void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getRowIdx());
|
|
|
|
Record.AddStmt(E->getColumnIdx());
|
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
|
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
|
|
|
}
|
|
|
|
|
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());
|
2020-07-10 02:27:32 +08:00
|
|
|
Record.AddStmt(E->getStride());
|
|
|
|
Record.AddSourceLocation(E->getColonLocFirst());
|
|
|
|
Record.AddSourceLocation(E->getColonLocSecond());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2015-08-25 22:24:04 +08:00
|
|
|
Code = serialization::EXPR_OMP_ARRAY_SECTION;
|
|
|
|
}
|
|
|
|
|
[OPENMP50]Add basic support for array-shaping operation.
Summary:
Added basic representation and parsing/sema handling of array-shaping
operations. Array shaping expression is an expression of form ([s0]..[sn])base,
where s0, ..., sn must be a positive integer, base - a pointer. This
expression is a kind of cast operation that converts pointer expression
into an array-like kind of expression.
Reviewers: rjmccall, rsmith, jdoerfert
Subscribers: guansong, arphaman, cfe-commits, caomhin, kkwli0
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74144
2020-02-05 22:33:05 +08:00
|
|
|
void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getDimensions().size());
|
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
for (Expr *Dim : E->getDimensions())
|
|
|
|
Record.AddStmt(Dim);
|
|
|
|
for (SourceRange SR : E->getBracketsRanges())
|
|
|
|
Record.AddSourceRange(SR);
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Code = serialization::EXPR_OMP_ARRAY_SHAPING;
|
|
|
|
}
|
|
|
|
|
2020-04-02 03:06:38 +08:00
|
|
|
void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->numOfIterators());
|
|
|
|
Record.AddSourceLocation(E->getIteratorKwLoc());
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
|
|
|
|
Record.AddDeclRef(E->getIteratorDecl(I));
|
|
|
|
Record.AddSourceLocation(E->getAssignLoc(I));
|
|
|
|
OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
|
|
|
|
Record.AddStmt(Range.Begin);
|
|
|
|
Record.AddStmt(Range.End);
|
|
|
|
Record.AddStmt(Range.Step);
|
|
|
|
Record.AddSourceLocation(E->getColonLoc(I));
|
|
|
|
if (Range.Step)
|
|
|
|
Record.AddSourceLocation(E->getSecondColonLoc(I));
|
2020-04-06 23:21:43 +08:00
|
|
|
// Serialize helpers
|
|
|
|
OMPIteratorHelperData &HD = E->getHelper(I);
|
|
|
|
Record.AddDeclRef(HD.CounterVD);
|
|
|
|
Record.AddStmt(HD.Upper);
|
|
|
|
Record.AddStmt(HD.Update);
|
|
|
|
Record.AddStmt(HD.CounterUpdate);
|
2020-04-02 03:06:38 +08:00
|
|
|
}
|
|
|
|
Code = serialization::EXPR_OMP_ITERATOR;
|
|
|
|
}
|
|
|
|
|
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());
|
2020-07-24 13:04:19 +08:00
|
|
|
Record.push_back(E->hasStoredFPFeatures());
|
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()));
|
2020-07-24 13:04:19 +08:00
|
|
|
if (E->hasStoredFPFeatures())
|
|
|
|
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CALL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
[AST] Add RecoveryExpr to retain expressions on semantic errors
Normally clang avoids creating expressions when it encounters semantic
errors, even if the parser knows which expression to produce.
This works well for the compiler. However, this is not ideal for
source-level tools that have to deal with broken code, e.g. clangd is
not able to provide navigation features even for names that compiler
knows how to resolve.
The new RecoveryExpr aims to capture the minimal set of information
useful for the tools that need to deal with incorrect code:
source range of the expression being dropped,
subexpressions of the expression.
We aim to make constructing RecoveryExprs as simple as possible to
ensure writing code to avoid dropping expressions is easy.
Producing RecoveryExprs can result in new code paths being taken in the
frontend. In particular, clang can produce some new diagnostics now and
we aim to suppress bogus ones based on Expr::containsErrors.
We deliberately produce RecoveryExprs only in the parser for now to
minimize the code affected by this patch. Producing RecoveryExprs in
Sema potentially allows to preserve more information (e.g. type of an
expression), but also results in more code being affected. E.g.
SFINAE checks will have to take presence of RecoveryExprs into account.
Initial implementation only works in C++ mode, as it relies on compiler
postponing diagnostics on dependent expressions. C and ObjC often do not
do this, so they require more work to make sure we do not produce too
many bogus diagnostics on the new expressions.
See documentation of RecoveryExpr for more details.
original patch from Ilya
This change is based on https://reviews.llvm.org/D61722
Reviewers: sammccall, rsmith
Reviewed By: sammccall, rsmith
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69330
2020-03-19 23:30:40 +08:00
|
|
|
void ASTStmtWriter::VisitRecoveryExpr(RecoveryExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(std::distance(E->children().begin(), E->children().end()));
|
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
for (Stmt *Child : E->children())
|
|
|
|
Record.AddStmt(Child);
|
|
|
|
Code = serialization::EXPR_RECOVERY;
|
|
|
|
}
|
|
|
|
|
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());
|
2020-09-12 22:54:14 +08:00
|
|
|
Record.push_back(E->hasStoredFPFeatures());
|
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);
|
2020-09-12 22:54:14 +08:00
|
|
|
|
|
|
|
if (E->hasStoredFPFeatures())
|
|
|
|
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
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);
|
2020-04-11 04:34:46 +08:00
|
|
|
bool HasFPFeatures = E->hasStoredFPFeatures();
|
|
|
|
// Write this first for easy access when deserializing, as they affect the
|
|
|
|
// size of the UnaryOperator.
|
|
|
|
Record.push_back(HasFPFeatures);
|
|
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2020-04-11 04:34:46 +08:00
|
|
|
if (HasFPFeatures)
|
|
|
|
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
|
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
|
|
|
|
2020-09-12 22:54:14 +08:00
|
|
|
if (E->path_size() == 0 && !E->hasStoredFPFeatures())
|
2014-07-27 12:19:32 +08:00
|
|
|
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());
|
2020-03-10 08:34:33 +08:00
|
|
|
Record.push_back(E->getTemplateDepth());
|
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());
|
2021-10-26 22:53:33 +08:00
|
|
|
for (ObjCAtCatchStmt *C : S->catch_stmts())
|
|
|
|
Record.AddStmt(C);
|
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());
|
2020-06-26 23:45:12 +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
|
|
|
}
|
|
|
|
|
2019-10-19 08:04:38 +08:00
|
|
|
void ASTStmtWriter::VisitCXXRewrittenBinaryOperator(
|
|
|
|
CXXRewrittenBinaryOperator *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isReversed());
|
|
|
|
Record.AddStmt(E->getSemanticForm());
|
|
|
|
Code = serialization::EXPR_CXX_REWRITTEN_BINARY_OPERATOR;
|
|
|
|
}
|
|
|
|
|
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);
|
2020-06-13 21:17:03 +08:00
|
|
|
Record.push_back(E->LambdaExprBits.NumCaptures);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceRange(E->IntroducerRange);
|
2020-06-13 21:17:03 +08:00
|
|
|
Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddSourceLocation(E->CaptureDefaultLoc);
|
2020-06-13 21:17:03 +08:00
|
|
|
Record.push_back(E->LambdaExprBits.ExplicitParams);
|
|
|
|
Record.push_back(E->LambdaExprBits.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
|
|
|
|
2020-07-02 21:13:35 +08:00
|
|
|
// Don't serialize the body. It belongs to the call operator declaration.
|
|
|
|
// LambdaExpr only stores a copy of the Stmt *.
|
2020-06-18 19:51:11 +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
|
|
|
}
|
|
|
|
|
2020-05-18 18:02:01 +08:00
|
|
|
void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
|
|
|
|
VisitCXXNamedCastExpr(E);
|
|
|
|
Code = serialization::EXPR_CXX_ADDRSPACE_CAST;
|
|
|
|
}
|
|
|
|
|
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());
|
2020-06-12 00:30:16 +08:00
|
|
|
Code = serialization::EXPR_BUILTIN_BIT_CAST;
|
2019-07-03 02:28:13 +08:00
|
|
|
}
|
|
|
|
|
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());
|
2020-03-11 05:06:25 +08:00
|
|
|
for (auto &Obj : E->getObjects()) {
|
|
|
|
if (auto *BD = Obj.dyn_cast<BlockDecl *>()) {
|
|
|
|
Record.push_back(serialization::COK_Block);
|
|
|
|
Record.AddDeclRef(BD);
|
|
|
|
} else if (auto *CLE = Obj.dyn_cast<CompoundLiteralExpr *>()) {
|
|
|
|
Record.push_back(serialization::COK_CompoundLiteral);
|
|
|
|
Record.AddStmt(CLE);
|
|
|
|
}
|
|
|
|
}
|
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);
|
2020-10-31 00:49:24 +08:00
|
|
|
Record.push_back(E->getNumArgs());
|
2010-06-24 16:57:31 +08:00
|
|
|
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());
|
2020-09-14 10:38:32 +08:00
|
|
|
Record.push_back(E->isReferenceParameter());
|
2016-04-07 01:06:00 +08:00
|
|
|
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);
|
2019-11-17 18:41:55 +08:00
|
|
|
Record.push_back(static_cast<bool>(E->getLifetimeExtendedTemporaryDecl()));
|
|
|
|
if (E->getLifetimeExtendedTemporaryDecl())
|
|
|
|
Record.AddDeclRef(E->getLifetimeExtendedTemporaryDecl());
|
|
|
|
else
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
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]);
|
2020-08-07 06:57:35 +08:00
|
|
|
Record.AddStmt(E->SubExprs[2]);
|
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());
|
Rework how UuidAttr, CXXUuidofExpr, and GUID template arguments and constants are represented.
Summary:
Previously, we treated CXXUuidofExpr as quite a special case: it was the
only kind of expression that could be a canonical template argument, it
could be a constant lvalue base object, and so on. In addition, we
represented the UUID value as a string, whose source form we did not
preserve faithfully, and that we partially parsed in multiple different
places.
With this patch, we create an MSGuidDecl object to represent the
implicit object of type 'struct _GUID' created by a UuidAttr. Each
UuidAttr holds a pointer to its 'struct _GUID' and its original
(as-written) UUID string. A non-value-dependent CXXUuidofExpr behaves
like a DeclRefExpr denoting that MSGuidDecl object. We cache an APValue
representation of the GUID on the MSGuidDecl and use it from constant
evaluation where needed.
This allows removing a lot of the special-case logic to handle these
expressions. Unfortunately, many parts of Clang assume there are only
a couple of interesting kinds of ValueDecl, so the total amount of
special-case logic is not really reduced very much.
This fixes a few bugs and issues:
* PR38490: we now support reading from GUID objects returned from
__uuidof during constant evaluation.
* Our Itanium mangling for a non-instantiation-dependent template
argument involving __uuidof no longer depends on which CXXUuidofExpr
template argument we happened to see first.
* We now predeclare ::_GUID, and permit use of __uuidof without
any header inclusion, better matching MSVC's behavior. We do not
predefine ::__s_GUID, though; that seems like a step too far.
* Our IR representation for GUID constants now uses the correct IR type
wherever possible. We will still fall back to using the
{i32, i16, i16, [8 x i8]}
layout if a definition of struct _GUID is not available. This is not
ideal: in principle the two layouts could have different padding.
Reviewers: rnk, jdoerfert
Subscribers: arphaman, cfe-commits, aeubanks
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78171
2020-04-12 13:15:29 +08:00
|
|
|
Record.AddDeclRef(E->getGuidDecl());
|
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.
|
|
|
|
//===----------------------------------------------------------------------===//
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
|
2021-03-04 07:15:32 +08:00
|
|
|
void ASTStmtWriter::VisitOMPCanonicalLoop(OMPCanonicalLoop *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
for (Stmt *SubStmt : S->SubStmts)
|
|
|
|
Record.AddStmt(SubStmt);
|
|
|
|
Code = serialization::STMT_OMP_CANONICAL_LOOP;
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeOMPChildren(E->Data);
|
2018-08-10 05:08:08 +08:00
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
2018-08-10 05:09:38 +08:00
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
|
|
|
|
2021-02-13 03:26:59 +08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) {
|
2014-02-27 16:29:12 +08:00
|
|
|
VisitStmt(D);
|
2021-02-13 03:26:59 +08:00
|
|
|
Record.writeUInt32(D->getLoopsNumber());
|
2013-07-19 11:13:43 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
}
|
|
|
|
|
2021-02-13 03:26:59 +08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
|
|
|
|
VisitOMPLoopBasedDirective(D);
|
|
|
|
}
|
|
|
|
|
2021-09-18 05:03:01 +08:00
|
|
|
void ASTStmtWriter::VisitOMPMetaDirective(OMPMetaDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_META_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:27:13 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
|
2014-02-27 16:29:12 +08:00
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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;
|
|
|
|
}
|
|
|
|
|
2021-10-06 23:02:27 +08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopTransformationDirective(
|
|
|
|
OMPLoopTransformationDirective *D) {
|
2021-02-13 03:26:59 +08:00
|
|
|
VisitOMPLoopBasedDirective(D);
|
2021-10-07 00:43:29 +08:00
|
|
|
Record.writeUInt32(D->getNumGeneratedLoops());
|
2021-10-06 23:02:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) {
|
|
|
|
VisitOMPLoopTransformationDirective(D);
|
2021-02-13 03:26:59 +08:00
|
|
|
Code = serialization::STMT_OMP_TILE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-06-11 03:24:17 +08:00
|
|
|
void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
|
2021-10-06 23:02:27 +08:00
|
|
|
VisitOMPLoopTransformationDirective(D);
|
2021-06-11 03:24:17 +08:00
|
|
|
Code = serialization::STMT_OMP_UNROLL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-18 12:14:57 +08:00
|
|
|
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
|
|
|
VisitOMPExecutableDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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;
|
|
|
|
}
|
|
|
|
|
2019-12-06 02:43:48 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterDirective(
|
|
|
|
OMPParallelMasterDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-08 16:12:03 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelSectionsDirective(
|
|
|
|
OMPParallelSectionsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
|
|
|
VisitOMPExecutableDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
|
|
|
VisitOMPExecutableDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->isXLHSInRHSPart());
|
|
|
|
Record.writeBool(D->isPostfixUpdate());
|
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);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-21 21:44:28 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
|
2016-01-20 03:15:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
|
|
|
|
OMPTargetEnterDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
VisitOMPExecutableDirective(D);
|
2020-04-27 23:37:35 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-01-27 02:48:41 +08:00
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-02-03 23:46:42 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelForDirective(
|
|
|
|
OMPTargetParallelForDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-02-03 23:46:42 +08:00
|
|
|
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);
|
2021-11-19 21:59:40 +08:00
|
|
|
Record.push_back(D->getNumClauses());
|
2014-07-18 18:17:07 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-06-18 20:14:09 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 19:26:11 +08:00
|
|
|
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2020-02-28 22:52:15 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2020-03-20 19:03:01 +08:00
|
|
|
void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SCAN_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 14:45:04 +08:00
|
|
|
void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-10-09 12:18:56 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
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);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeEnum(D->getCancelRegion());
|
2015-07-01 14:57:41 +08:00
|
|
|
Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-02 19:25:17 +08:00
|
|
|
void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeEnum(D->getCancelRegion());
|
2015-07-02 19:25:17 +08:00
|
|
|
Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-01 12:18:41 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
2015-12-01 12:18:41 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-10-11 04:13:02 +08:00
|
|
|
void ASTStmtWriter::VisitOMPMasterTaskLoopDirective(
|
|
|
|
OMPMasterTaskLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
2019-10-11 04:13:02 +08:00
|
|
|
Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-19 00:47:35 +08:00
|
|
|
void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective(
|
|
|
|
OMPMasterTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-15 01:17:41 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective(
|
|
|
|
OMPParallelMasterTaskLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
2019-10-15 01:17:41 +08:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-25 22:27:13 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterTaskLoopSimdDirective(
|
|
|
|
OMPParallelMasterTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_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);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-06-27 22:55:37 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
|
|
|
|
OMPDistributeParallelForDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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);
|
|
|
|
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);
|
[OPENMP]Redesign of OMPExecutableDirective/OMPDeclarativeDirective representation.
Summary:
Introduced OMPChildren class to handle all associated clauses, statement
and child expressions/statements. It allows to represent some directives
more correctly (like flush, depobj etc. with pseudo clauses, ordered
depend directives, which are standalone, and target data directives).
Also, it will make easier to avoid using of CapturedStmt in directives,
if required (atomic, tile etc. directives).
Also, it simplifies serialization/deserialization of the
executable/declarative directives.
Reduces number of allocation operations for mapper declarations.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, jfb, cfe-commits, sstefan1, aaron.ballman, caomhin
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83261
2020-06-27 05:42:31 +08:00
|
|
|
Record.writeBool(D->hasCancel());
|
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;
|
|
|
|
}
|
|
|
|
|
2021-03-16 04:09:46 +08:00
|
|
|
void ASTStmtWriter::VisitOMPInteropDirective(OMPInteropDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_INTEROP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-03-23 09:13:29 +08:00
|
|
|
void ASTStmtWriter::VisitOMPDispatchDirective(OMPDispatchDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Record.AddSourceLocation(D->getTargetCallLoc());
|
|
|
|
Code = serialization::STMT_OMP_DISPATCH_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-04-10 03:00:36 +08:00
|
|
|
void ASTStmtWriter::VisitOMPMaskedDirective(OMPMaskedDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASKED_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-10-28 23:10:40 +08:00
|
|
|
void ASTStmtWriter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_GENERIC_LOOP_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();
|
|
|
|
}
|