2010-08-18 23:56:31 +00:00
|
|
|
//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
|
2009-04-27 06:20:01 +00:00
|
|
|
//
|
2019-01-19 08:50:56 +00: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 06:20:01 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-08-09 23:08:25 +00:00
|
|
|
///
|
|
|
|
/// \file
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Implements serialization for Statements and Expressions.
|
2013-08-09 23:08:25 +00:00
|
|
|
///
|
2009-04-27 06:20:01 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2023-08-02 14:00:16 +02:00
|
|
|
#include "clang/AST/ASTConcept.h"
|
2012-07-04 20:19:54 +00:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-09-09 23:08:42 +00:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2009-04-27 06:20:01 +00:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2011-01-15 01:15:58 +00:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2023-08-02 14:00:16 +02:00
|
|
|
#include "clang/AST/ExprOpenMP.h"
|
2009-04-27 06:20:01 +00:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2013-05-03 00:10:13 +00:00
|
|
|
#include "clang/Lex/Token.h"
|
2023-08-02 14:00:16 +02:00
|
|
|
#include "clang/Sema/DeclSpec.h"
|
|
|
|
#include "clang/Serialization/ASTRecordWriter.h"
|
2019-07-03 22:40:07 +00:00
|
|
|
#include "llvm/Bitstream/BitstreamWriter.h"
|
2009-04-27 06:20:01 +00:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Statement/expression serialization
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-30 08:49:18 +00:00
|
|
|
namespace clang {
|
2013-07-19 03:13:43 +00:00
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
|
2010-08-18 23:56:21 +00:00
|
|
|
ASTWriter &Writer;
|
2016-04-06 17:06:00 +00:00
|
|
|
ASTRecordWriter Record;
|
2009-04-27 06:20:01 +00:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
serialization::StmtCode Code;
|
2011-06-03 02:27:19 +00:00
|
|
|
unsigned AbbrevToUse;
|
2009-04-27 06:20:01 +00:00
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
/// A helper that can help us to write a packed bit across function
|
|
|
|
/// calls. For example, we may write seperate bits in seperate functions:
|
|
|
|
///
|
|
|
|
/// void VisitA(A* a) {
|
|
|
|
/// Record.push_back(a->isSomething());
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// void Visitb(B *b) {
|
|
|
|
/// VisitA(b);
|
|
|
|
/// Record.push_back(b->isAnother());
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// In such cases, it'll be better if we can pack these 2 bits. We achieve
|
|
|
|
/// this by writing a zero value in `VisitA` and recorded that first and add
|
|
|
|
/// the new bit to the recorded value.
|
|
|
|
class PakedBitsWriter {
|
|
|
|
public:
|
|
|
|
PakedBitsWriter(ASTRecordWriter &Record) : RecordRef(Record) {}
|
|
|
|
~PakedBitsWriter() { assert(!CurrentIndex); }
|
|
|
|
|
|
|
|
void addBit(bool Value) {
|
|
|
|
assert(CurrentIndex && "Writing Bits without recording first!");
|
|
|
|
PackingBits.addBit(Value);
|
|
|
|
}
|
|
|
|
void addBits(uint32_t Value, uint32_t BitsWidth) {
|
|
|
|
assert(CurrentIndex && "Writing Bits without recording first!");
|
|
|
|
PackingBits.addBits(Value, BitsWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeBits() {
|
|
|
|
if (!CurrentIndex)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RecordRef[*CurrentIndex] = (uint32_t)PackingBits;
|
|
|
|
CurrentIndex = std::nullopt;
|
|
|
|
PackingBits.reset(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateBits() {
|
|
|
|
writeBits();
|
|
|
|
|
|
|
|
CurrentIndex = RecordRef.size();
|
|
|
|
RecordRef.push_back(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
BitsPacker PackingBits;
|
|
|
|
ASTRecordWriter &RecordRef;
|
|
|
|
std::optional<unsigned> CurrentIndex;
|
|
|
|
};
|
|
|
|
|
|
|
|
PakedBitsWriter CurrentPackingBits;
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
public:
|
2010-08-18 23:56:27 +00:00
|
|
|
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
|
2016-04-06 17:06:00 +00:00
|
|
|
: Writer(Writer), Record(Writer, Record),
|
2023-12-21 10:30:12 +08:00
|
|
|
Code(serialization::STMT_NULL_PTR), AbbrevToUse(0),
|
|
|
|
CurrentPackingBits(this->Record) {}
|
2016-04-06 17:06:00 +00:00
|
|
|
|
|
|
|
ASTStmtWriter(const ASTStmtWriter&) = delete;
|
2023-05-14 19:49:22 -07:00
|
|
|
ASTStmtWriter &operator=(const ASTStmtWriter &) = delete;
|
2016-04-06 17:06:00 +00:00
|
|
|
|
2016-04-06 20:12:34 +00:00
|
|
|
uint64_t Emit() {
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.writeBits();
|
2016-04-06 17:06:00 +00:00
|
|
|
assert(Code != serialization::STMT_NULL_PTR &&
|
|
|
|
"unhandled sub-statement writing AST file");
|
|
|
|
return Record.EmitStmt(Code, AbbrevToUse);
|
|
|
|
}
|
2012-01-27 09:46:47 +00:00
|
|
|
|
2015-12-29 18:15:14 +00:00
|
|
|
void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
|
|
|
|
const TemplateArgumentLoc *Args);
|
2009-04-27 06:20:01 +00:00
|
|
|
|
|
|
|
void VisitStmt(Stmt *S);
|
2011-07-15 07:00:14 +00:00
|
|
|
#define STMT(Type, Base) \
|
|
|
|
void Visit##Type(Type *);
|
|
|
|
#include "clang/AST/StmtNodes.inc"
|
2009-04-27 06:20:01 +00:00
|
|
|
};
|
2015-06-22 23:07:51 +00:00
|
|
|
}
|
2009-04-27 06:20:01 +00:00
|
|
|
|
2015-12-29 18:15:14 +00:00
|
|
|
void ASTStmtWriter::AddTemplateKWAndArgsInfo(
|
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
|
|
|
|
Record.AddSourceLocation(ArgInfo.LAngleLoc);
|
|
|
|
Record.AddSourceLocation(ArgInfo.RAngleLoc);
|
2015-12-29 18:15:14 +00:00
|
|
|
for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTemplateArgumentLoc(Args[i]);
|
2010-06-28 09:31:48 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitStmt(Stmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00: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-27 18:43:27 +00:00
|
|
|
Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_NULL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(S->size());
|
|
|
|
Record.push_back(S->hasStoredFPFeatures());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2014-03-17 14:19:37 +00:00
|
|
|
for (auto *CS : S->body())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(CS);
|
[FPEnv] Allow CompoundStmt to keep FP options
This is a recommit of b822efc7404bf09ccfdc1ab7657475026966c3b2,
reverted in dc34d8df4c48b3a8f474360970cae8a58e6c84f0. The commit caused
fails because the test ast-print-fp-pragmas.c did not specify particular
target, and it failed on targets which do not support constrained
intrinsics. The original commit message is below.
AST does not have special nodes for pragmas. Instead a pragma modifies
some state variables of Sema, which in turn results in modified
attributes of AST nodes. This technique applies to floating point
operations as well. Every AST node that can depend on FP options keeps
current set of them.
This technique works well for options like exception behavior or fast
math options. They represent instructions to the compiler how to modify
code generation for the affected nodes. However treatment of FP control
modes has problems with this technique. Modifying FP control mode
(like rounding direction) usually requires operations on hardware, like
writing to control registers. It must be done prior to the first
operation that depends on the control mode. In particular, such
operations are required for implementation of `pragma STDC FENV_ROUND`,
compiler should set up necessary rounding direction at the beginning of
compound statement where the pragma occurs. As there is no representation
for pragmas in AST, the code generation becomes a complicated task in
this case.
To solve this issue FP options are kept inside CompoundStmt. Unlike to FP
options in expressions, these does not affect any operation on FP values,
but only inform the codegen about the FP options that act in the body of
the statement. As all pragmas that modify FP environment may occurs only
at the start of compound statement or at global level, such solution
works for all relevant pragmas. The options are kept as a difference
from the options in the enclosing compound statement or default options,
it helps codegen to set only changed control modes.
Differential Revision: https://reviews.llvm.org/D123952
2022-07-01 18:32:26 +07:00
|
|
|
if (S->hasStoredFPFeatures())
|
|
|
|
Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getLBracLoc());
|
|
|
|
Record.AddSourceLocation(S->getRBracLoc());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
|
|
|
if (!S->hasStoredFPFeatures())
|
|
|
|
AbbrevToUse = Writer.getCompoundStmtAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_COMPOUND;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2010-06-28 22:28:35 +00:00
|
|
|
Record.push_back(Writer.getSwitchCaseID(S));
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
|
|
|
Record.AddSourceLocation(S->getColonLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitSwitchCase(S);
|
2018-10-28 12:30:53 +00:00
|
|
|
Record.push_back(S->caseStmtIsGNURange());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getLHS());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
2018-10-28 12:30:53 +00:00
|
|
|
if (S->caseStmtIsGNURange()) {
|
|
|
|
Record.AddStmt(S->getRHS());
|
|
|
|
Record.AddSourceLocation(S->getEllipsisLoc());
|
|
|
|
}
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_CASE;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitSwitchCase(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getSubStmt());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_DEFAULT;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
|
2009-04-27 06:20:01 +00: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-17 22:06:32 -07:00
|
|
|
Record.push_back(S->isSideEntry());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(S->getDecl());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
|
|
|
Record.AddSourceLocation(S->getIdentLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_LABEL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2012-04-14 00:33:13 +00:00
|
|
|
void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
|
|
|
|
VisitStmt(S);
|
2012-07-09 10:04:07 +00:00
|
|
|
Record.push_back(S->getAttrs().size());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddAttributes(S->getAttrs());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
|
|
|
Record.AddSourceLocation(S->getAttrLoc());
|
2012-04-14 00:33:13 +00:00
|
|
|
Code = serialization::STMT_ATTRIBUTED;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2018-10-27 21:12:20 +00:00
|
|
|
|
|
|
|
bool HasElse = S->getElse() != nullptr;
|
|
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
|
|
bool HasInit = S->getInit() != nullptr;
|
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
|
|
|
|
|
|
|
CurrentPackingBits.addBit(HasElse);
|
|
|
|
CurrentPackingBits.addBit(HasVar);
|
|
|
|
CurrentPackingBits.addBit(HasInit);
|
2021-10-05 08:02:53 -04:00
|
|
|
Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getThen());
|
2018-10-27 21:12:20 +00:00
|
|
|
if (HasElse)
|
|
|
|
Record.AddStmt(S->getElse());
|
|
|
|
if (HasVar)
|
PR60985: Fix merging of lambda closure types across modules.
Previously, distinct lambdas would get merged, and multiple definitions
of the same lambda would not get merged, because we attempted to
identify lambdas by their ordinal position within their lexical
DeclContext. This failed for lambdas within namespace-scope variables
and within variable templates, where the lexical position in the context
containing the variable didn't uniquely identify the lambda.
In this patch, we instead identify lambda closure types by index within
their context declaration, which does uniquely identify them in a way
that's consistent across modules.
This change causes a deserialization cycle between the type of a
variable with deduced type and a lambda appearing as the initializer of
the variable -- reading the variable's type requires reading and merging
the lambda, and reading the lambda requires reading and merging the
variable. This is addressed by deferring loading the deduced type of a
variable until after we finish recursive deserialization.
This also exposes a pre-existing subtle issue where loading a
variable declaration would trigger immediate loading of its initializer,
which could recursively refer back to properties of the variable. This
particularly causes problems if the initializer contains a
lambda-expression, but can be problematic in general. That is addressed
by switching to lazily loading the initializers of variables rather than
always loading them with the variable declaration. As well as fixing a
deserialization cycle, that should improve laziness of deserialization
in general.
LambdaDefinitionData had 63 spare bits in it, presumably caused by an
off-by-one-error in some previous change. This change claims 32 of those bits
as a counter for the lambda within its context. We could probably move the
numbering to separate storage, like we do for the device-side mangling number,
to optimize the likely-common case where all three numbers (host-side mangling
number, device-side mangling number, and index within the context declaration)
are zero, but that's not done in this change.
Fixes #60985.
Reviewed By: #clang-language-wg, aaron.ballman
Differential Revision: https://reviews.llvm.org/D145737
2023-03-30 14:21:31 -07:00
|
|
|
Record.AddStmt(S->getConditionVariableDeclStmt());
|
2018-10-27 21:12:20 +00:00
|
|
|
if (HasInit)
|
|
|
|
Record.AddStmt(S->getInit());
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getIfLoc());
|
2020-08-10 16:29:33 -07:00
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2018-10-27 21:12:20 +00:00
|
|
|
if (HasElse)
|
|
|
|
Record.AddSourceLocation(S->getElseLoc());
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_IF;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2018-10-29 16:12:37 +00: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-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getBody());
|
2018-10-29 16:12:37 +00:00
|
|
|
if (HasInit)
|
|
|
|
Record.AddStmt(S->getInit());
|
|
|
|
if (HasVar)
|
PR60985: Fix merging of lambda closure types across modules.
Previously, distinct lambdas would get merged, and multiple definitions
of the same lambda would not get merged, because we attempted to
identify lambdas by their ordinal position within their lexical
DeclContext. This failed for lambdas within namespace-scope variables
and within variable templates, where the lexical position in the context
containing the variable didn't uniquely identify the lambda.
In this patch, we instead identify lambda closure types by index within
their context declaration, which does uniquely identify them in a way
that's consistent across modules.
This change causes a deserialization cycle between the type of a
variable with deduced type and a lambda appearing as the initializer of
the variable -- reading the variable's type requires reading and merging
the lambda, and reading the lambda requires reading and merging the
variable. This is addressed by deferring loading the deduced type of a
variable until after we finish recursive deserialization.
This also exposes a pre-existing subtle issue where loading a
variable declaration would trigger immediate loading of its initializer,
which could recursively refer back to properties of the variable. This
particularly causes problems if the initializer contains a
lambda-expression, but can be problematic in general. That is addressed
by switching to lazily loading the initializers of variables rather than
always loading them with the variable declaration. As well as fixing a
deserialization cycle, that should improve laziness of deserialization
in general.
LambdaDefinitionData had 63 spare bits in it, presumably caused by an
off-by-one-error in some previous change. This change claims 32 of those bits
as a counter for the lambda within its context. We could probably move the
numbering to separate storage, like we do for the device-side mangling number,
to optimize the likely-common case where all three numbers (host-side mangling
number, device-side mangling number, and index within the context declaration)
are zero, but that's not done in this change.
Fixes #60985.
Reviewed By: #clang-language-wg, aaron.ballman
Differential Revision: https://reviews.llvm.org/D145737
2023-03-30 14:21:31 -07:00
|
|
|
Record.AddStmt(S->getConditionVariableDeclStmt());
|
2018-10-29 16:12:37 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getSwitchLoc());
|
2020-08-10 16:29:33 -07:00
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2018-10-29 16:12:37 +00:00
|
|
|
|
2009-09-09 15:08:12 +00:00
|
|
|
for (SwitchCase *SC = S->getSwitchCaseList(); SC;
|
2009-04-27 06:20:01 +00:00
|
|
|
SC = SC->getNextSwitchCase())
|
2010-06-28 22:28:35 +00:00
|
|
|
Record.push_back(Writer.RecordSwitchCaseID(SC));
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_SWITCH;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2018-10-30 13:42:41 +00:00
|
|
|
|
|
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
|
|
Record.push_back(HasVar);
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getBody());
|
2018-10-30 13:42:41 +00:00
|
|
|
if (HasVar)
|
PR60985: Fix merging of lambda closure types across modules.
Previously, distinct lambdas would get merged, and multiple definitions
of the same lambda would not get merged, because we attempted to
identify lambdas by their ordinal position within their lexical
DeclContext. This failed for lambdas within namespace-scope variables
and within variable templates, where the lexical position in the context
containing the variable didn't uniquely identify the lambda.
In this patch, we instead identify lambda closure types by index within
their context declaration, which does uniquely identify them in a way
that's consistent across modules.
This change causes a deserialization cycle between the type of a
variable with deduced type and a lambda appearing as the initializer of
the variable -- reading the variable's type requires reading and merging
the lambda, and reading the lambda requires reading and merging the
variable. This is addressed by deferring loading the deduced type of a
variable until after we finish recursive deserialization.
This also exposes a pre-existing subtle issue where loading a
variable declaration would trigger immediate loading of its initializer,
which could recursively refer back to properties of the variable. This
particularly causes problems if the initializer contains a
lambda-expression, but can be problematic in general. That is addressed
by switching to lazily loading the initializers of variables rather than
always loading them with the variable declaration. As well as fixing a
deserialization cycle, that should improve laziness of deserialization
in general.
LambdaDefinitionData had 63 spare bits in it, presumably caused by an
off-by-one-error in some previous change. This change claims 32 of those bits
as a counter for the lambda within its context. We could probably move the
numbering to separate storage, like we do for the device-side mangling number,
to optimize the likely-common case where all three numbers (host-side mangling
number, device-side mangling number, and index within the context declaration)
are zero, but that's not done in this change.
Fixes #60985.
Reviewed By: #clang-language-wg, aaron.ballman
Differential Revision: https://reviews.llvm.org/D145737
2023-03-30 14:21:31 -07:00
|
|
|
Record.AddStmt(S->getConditionVariableDeclStmt());
|
2018-10-30 13:42:41 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getWhileLoc());
|
2020-07-09 23:19:06 -04:00
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_WHILE;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getCond());
|
|
|
|
Record.AddStmt(S->getBody());
|
|
|
|
Record.AddSourceLocation(S->getDoLoc());
|
|
|
|
Record.AddSourceLocation(S->getWhileLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_DO;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitForStmt(ForStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getInit());
|
|
|
|
Record.AddStmt(S->getCond());
|
PR60985: Fix merging of lambda closure types across modules.
Previously, distinct lambdas would get merged, and multiple definitions
of the same lambda would not get merged, because we attempted to
identify lambdas by their ordinal position within their lexical
DeclContext. This failed for lambdas within namespace-scope variables
and within variable templates, where the lexical position in the context
containing the variable didn't uniquely identify the lambda.
In this patch, we instead identify lambda closure types by index within
their context declaration, which does uniquely identify them in a way
that's consistent across modules.
This change causes a deserialization cycle between the type of a
variable with deduced type and a lambda appearing as the initializer of
the variable -- reading the variable's type requires reading and merging
the lambda, and reading the lambda requires reading and merging the
variable. This is addressed by deferring loading the deduced type of a
variable until after we finish recursive deserialization.
This also exposes a pre-existing subtle issue where loading a
variable declaration would trigger immediate loading of its initializer,
which could recursively refer back to properties of the variable. This
particularly causes problems if the initializer contains a
lambda-expression, but can be problematic in general. That is addressed
by switching to lazily loading the initializers of variables rather than
always loading them with the variable declaration. As well as fixing a
deserialization cycle, that should improve laziness of deserialization
in general.
LambdaDefinitionData had 63 spare bits in it, presumably caused by an
off-by-one-error in some previous change. This change claims 32 of those bits
as a counter for the lambda within its context. We could probably move the
numbering to separate storage, like we do for the device-side mangling number,
to optimize the likely-common case where all three numbers (host-side mangling
number, device-side mangling number, and index within the context declaration)
are zero, but that's not done in this change.
Fixes #60985.
Reviewed By: #clang-language-wg, aaron.ballman
Differential Revision: https://reviews.llvm.org/D145737
2023-03-30 14:21:31 -07:00
|
|
|
Record.AddStmt(S->getConditionVariableDeclStmt());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getInc());
|
|
|
|
Record.AddStmt(S->getBody());
|
|
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_FOR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(S->getLabel());
|
|
|
|
Record.AddSourceLocation(S->getGotoLoc());
|
|
|
|
Record.AddSourceLocation(S->getLabelLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_GOTO;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getGotoLoc());
|
|
|
|
Record.AddSourceLocation(S->getStarLoc());
|
|
|
|
Record.AddStmt(S->getTarget());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_INDIRECT_GOTO;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getContinueLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_CONTINUE;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getBreakLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_BREAK;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2018-10-30 14:40:49 +00:00
|
|
|
|
|
|
|
bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
|
|
|
|
Record.push_back(HasNRVOCandidate);
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getRetValue());
|
2018-10-30 14:40:49 +00:00
|
|
|
if (HasNRVOCandidate)
|
|
|
|
Record.AddDeclRef(S->getNRVOCandidate());
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getReturnLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_RETURN;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2018-08-09 21:05:56 +00:00
|
|
|
Record.AddSourceLocation(S->getBeginLoc());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getEndLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
DeclGroupRef DG = S->getDeclGroup();
|
|
|
|
for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(*D);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_DECL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2013-05-03 00:10:13 +00:00
|
|
|
void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getNumOutputs());
|
|
|
|
Record.push_back(S->getNumInputs());
|
|
|
|
Record.push_back(S->getNumClobbers());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getAsmLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(S->isVolatile());
|
|
|
|
Record.push_back(S->isSimple());
|
2013-05-03 00:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
|
|
|
|
VisitAsmStmt(S);
|
2019-06-03 15:57:25 +00:00
|
|
|
Record.push_back(S->getNumLabels());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
|
|
Record.AddStmt(S->getAsmString());
|
2009-04-27 06:20:01 +00:00
|
|
|
|
|
|
|
// Outputs
|
2018-07-30 19:24:48 +00:00
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddIdentifierRef(S->getOutputIdentifier(I));
|
|
|
|
Record.AddStmt(S->getOutputConstraintLiteral(I));
|
|
|
|
Record.AddStmt(S->getOutputExpr(I));
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddIdentifierRef(S->getInputIdentifier(I));
|
|
|
|
Record.AddStmt(S->getInputConstraintLiteral(I));
|
|
|
|
Record.AddStmt(S->getInputExpr(I));
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clobbers
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getClobberStringLiteral(I));
|
2009-04-27 06:20:01 +00:00
|
|
|
|
2019-06-03 15:57:25 +00:00
|
|
|
// Labels
|
2023-05-22 10:10:49 +00:00
|
|
|
for (unsigned I = 0, N = S->getNumLabels(); I != N; ++I) {
|
|
|
|
Record.AddIdentifierRef(S->getLabelIdentifier(I));
|
|
|
|
Record.AddStmt(S->getLabelExpr(I));
|
|
|
|
}
|
2019-06-03 15:57:25 +00:00
|
|
|
|
2012-08-25 00:11:56 +00:00
|
|
|
Code = serialization::STMT_GCCASM;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2012-06-11 20:47:18 +00:00
|
|
|
void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
|
2013-05-03 00:10:13 +00:00
|
|
|
VisitAsmStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getLBraceLoc());
|
|
|
|
Record.AddSourceLocation(S->getEndLoc());
|
2013-05-03 00:10:13 +00:00
|
|
|
Record.push_back(S->getNumAsmToks());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddString(S->getAsmString());
|
2013-05-03 00:10:13 +00:00
|
|
|
|
|
|
|
// Tokens
|
|
|
|
for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
|
2016-04-06 17:06:00 +00:00
|
|
|
// FIXME: Move this to ASTRecordWriter?
|
|
|
|
Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
|
2013-05-03 00:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clobbers
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddString(S->getClobber(I));
|
2013-05-03 00:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Outputs
|
2017-07-25 18:01:49 +00:00
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getOutputExpr(I));
|
|
|
|
Record.AddString(S->getOutputConstraint(I));
|
2013-05-03 00:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getInputExpr(I));
|
|
|
|
Record.AddString(S->getInputConstraint(I));
|
2013-05-03 00:10:13 +00:00
|
|
|
}
|
2012-08-24 23:51:02 +00:00
|
|
|
|
|
|
|
Code = serialization::STMT_MSASM;
|
2012-06-11 20:47:18 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 18:01:49 +00: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 06:02:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
|
2017-07-25 18:01:49 +00: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 06:02:45 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 18:01:49 +00:00
|
|
|
void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
|
|
|
|
VisitCoroutineSuspendExpr(E);
|
|
|
|
Record.push_back(E->isImplicit());
|
|
|
|
Code = serialization::EXPR_COAWAIT;
|
2015-10-27 06:02:45 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 18:01:49 +00:00
|
|
|
void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
|
|
|
|
VisitCoroutineSuspendExpr(E);
|
|
|
|
Code = serialization::EXPR_COYIELD;
|
2017-03-06 23:38:15 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 18:01:49 +00: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 06:02:45 +00:00
|
|
|
}
|
|
|
|
|
2020-01-18 09:11:43 +02:00
|
|
|
static void
|
|
|
|
addConstraintSatisfaction(ASTRecordWriter &Record,
|
|
|
|
const ASTConstraintSatisfaction &Satisfaction) {
|
2019-12-06 01:30:21 +02:00
|
|
|
Record.push_back(Satisfaction.IsSatisfied);
|
2022-09-26 06:57:25 -07:00
|
|
|
Record.push_back(Satisfaction.ContainsErrors);
|
2019-12-06 01:30:21 +02:00
|
|
|
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 09:11:43 +02: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);
|
2022-10-24 12:20:36 -07:00
|
|
|
Record.AddDeclRef(E->getSpecializationDecl());
|
2023-08-02 14:00:16 +02:00
|
|
|
const ConceptReference *CR = E->getConceptReference();
|
|
|
|
Record.push_back(CR != nullptr);
|
|
|
|
if (CR)
|
|
|
|
Record.AddConceptReference(CR);
|
2020-01-18 09:11:43 +02:00
|
|
|
if (!E->isValueDependent())
|
|
|
|
addConstraintSatisfaction(Record, E->getSatisfaction());
|
2019-12-06 01:30:21 +02:00
|
|
|
|
2019-10-15 15:24:26 +00:00
|
|
|
Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
|
|
|
|
}
|
|
|
|
|
2020-01-18 09:11:43 +02: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);
|
2022-11-29 14:05:53 +01:00
|
|
|
Record.push_back(NestedReq->hasInvalidConstraint());
|
|
|
|
if (NestedReq->hasInvalidConstraint()) {
|
|
|
|
Record.AddString(NestedReq->getInvalidConstraintEntity());
|
|
|
|
addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
|
2020-01-18 09:11:43 +02:00
|
|
|
} else {
|
2022-11-29 14:05:53 +01:00
|
|
|
Record.AddStmt(NestedReq->getConstraintExpr());
|
2020-01-18 09:11:43 +02:00
|
|
|
if (!NestedReq->isDependent())
|
|
|
|
addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Implement mangling rules for C++20 concepts and requires-expressions.
This implements proposals from:
- https://github.com/itanium-cxx-abi/cxx-abi/issues/24: mangling for
constraints, requires-clauses, requires-expressions.
- https://github.com/itanium-cxx-abi/cxx-abi/issues/31: requires-clauses and
template parameters in a lambda expression are mangled into the <lambda-sig>.
- https://github.com/itanium-cxx-abi/cxx-abi/issues/47 (STEP 3): mangling for
template argument is prefixed by mangling of template parameter declaration
if it's not "obvious", for example because the template parameter is
constrained (we already implemented STEP 1 and STEP 2).
This changes the manglings for a few cases:
- Functions and function templates with constraints.
- Function templates with template parameters with deduced types:
`typename<auto N> void f();`
- Function templates with template template parameters where the argument has a
different template-head:
`template<template<typename...T>> void f(); f<std::vector>();`
In each case where a mangling changed, the change fixes a mangling collision.
Note that only function templates are affected, not class templates or variable
templates, and only new constructs (template parameters with deduced types,
constrained templates) and esoteric constructs (templates with template
template parameters with non-matching template template arguments, most of
which Clang still does not accept by default due to
`-frelaxed-template-template-args` not being enabled by default), so the risk
to ABI stability from this change is relatively low. Nonetheless,
`-fclang-abi-compat=17` can be used to restore the old manglings for cases
which we could successfully but incorrectly mangle before.
Fixes #48216, #49884, #61273
Reviewed By: erichkeane, #libc_abi
Differential Revision: https://reviews.llvm.org/D147655
2023-09-12 18:53:54 -07:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2020-01-18 09:11:43 +02:00
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
|
|
|
|
Code = serialization::EXPR_REQUIRES;
|
|
|
|
}
|
|
|
|
|
2019-10-15 15:24:26 +00:00
|
|
|
|
2013-04-16 18:53:08 +00:00
|
|
|
void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
|
|
|
|
VisitStmt(S);
|
2013-05-03 19:20:19 +00:00
|
|
|
// NumCaptures
|
|
|
|
Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
|
|
|
|
|
2013-05-04 03:59:06 +00:00
|
|
|
// CapturedDecl and captured region kind
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(S->getCapturedDecl());
|
2013-05-04 03:59:06 +00:00
|
|
|
Record.push_back(S->getCapturedRegionKind());
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(S->getCapturedRecordDecl());
|
2013-05-03 19:20:19 +00:00
|
|
|
|
|
|
|
// Capture inits
|
2014-03-14 19:41:04 +00:00
|
|
|
for (auto *I : S->capture_inits())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(I);
|
2013-05-03 19:20:19 +00:00
|
|
|
|
|
|
|
// Body
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getCapturedStmt());
|
2013-05-03 19:20:19 +00:00
|
|
|
|
|
|
|
// Captures
|
2014-03-14 18:08:33 +00:00
|
|
|
for (const auto &I : S->captures()) {
|
2014-10-29 12:21:55 +00:00
|
|
|
if (I.capturesThis() || I.capturesVariableArrayType())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(nullptr);
|
2013-05-03 19:20:19 +00:00
|
|
|
else
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(I.getCapturedVar());
|
2014-03-14 18:08:33 +00:00
|
|
|
Record.push_back(I.getCaptureKind());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(I.getLocation());
|
2013-05-03 19:20:19 +00:00
|
|
|
}
|
2013-04-16 18:53:08 +00:00
|
|
|
|
2013-05-03 19:20:19 +00:00
|
|
|
Code = serialization::STMT_CAPTURED;
|
2013-04-16 18:53:08 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitExpr(Expr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(E);
|
2023-12-07 17:01:06 +08:00
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
|
|
|
CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5);
|
|
|
|
CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
|
|
|
|
CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
|
2023-12-15 14:30:24 -08:00
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
Record.AddTypeRef(E->getType());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2018-10-31 03:48:47 +00:00
|
|
|
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
|
|
|
|
VisitExpr(E);
|
2020-06-21 13:02:48 +01: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);
|
|
|
|
|
2023-11-04 13:28:02 +03:00
|
|
|
switch (E->getResultStorageKind()) {
|
|
|
|
case ConstantResultStorageKind::None:
|
2020-06-21 13:02:48 +01:00
|
|
|
break;
|
2023-11-04 13:28:02 +03:00
|
|
|
case ConstantResultStorageKind::Int64:
|
[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 10:24:47 +00:00
|
|
|
Record.push_back(E->Int64Result());
|
|
|
|
break;
|
2023-11-04 13:28:02 +03:00
|
|
|
case ConstantResultStorageKind::APValue:
|
[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 10:24:47 +00:00
|
|
|
Record.AddAPValue(E->APValueResult());
|
2020-06-21 13:02:48 +01:00
|
|
|
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 10:24:47 +00:00
|
|
|
}
|
2020-06-21 13:02:48 +01:00
|
|
|
|
2018-10-31 03:48:47 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Code = serialization::EXPR_CONSTANT;
|
|
|
|
}
|
|
|
|
|
2021-04-23 08:22:35 -07: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-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2018-10-27 19:21:19 +00:00
|
|
|
|
|
|
|
bool HasFunctionName = E->getFunctionName() != nullptr;
|
|
|
|
Record.push_back(HasFunctionName);
|
2023-11-05 15:36:50 +03:00
|
|
|
Record.push_back(
|
|
|
|
llvm::to_underlying(E->getIdentKind())); // FIXME: stable encoding
|
2023-05-07 11:24:48 -07:00
|
|
|
Record.push_back(E->isTransparent());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2018-10-27 19:21:19 +00:00
|
|
|
if (HasFunctionName)
|
|
|
|
Record.AddStmt(E->getFunctionName());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_PREDEFINED;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2010-07-08 13:09:47 +00:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->hadMultipleCandidates());
|
|
|
|
CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture());
|
|
|
|
CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
|
|
|
|
CurrentPackingBits.addBit(E->isImmediateEscalating());
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl());
|
|
|
|
CurrentPackingBits.addBit(E->hasQualifier());
|
|
|
|
CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
|
2010-07-08 13:09:47 +00:00
|
|
|
|
2012-01-27 09:46:47 +00:00
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2011-02-04 12:01:24 +00:00
|
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(NumTemplateArgs);
|
2011-02-04 12:01:24 +00:00
|
|
|
}
|
2010-07-08 13:09:47 +00:00
|
|
|
|
2011-06-03 02:27:19 +00:00
|
|
|
DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
|
|
|
|
|
2012-01-27 09:46:47 +00:00
|
|
|
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
|
2011-06-03 02:27:19 +00:00
|
|
|
(E->getDecl() == E->getFoundDecl()) &&
|
2023-12-21 16:35:20 +08:00
|
|
|
nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary) {
|
2011-06-03 02:27:19 +00:00
|
|
|
AbbrevToUse = Writer.getDeclRefExprAbbrev();
|
|
|
|
}
|
|
|
|
|
2011-03-06 18:19:42 +00:00
|
|
|
if (E->hasQualifier())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
2011-03-06 18:19:42 +00: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-01 23:48:14 +00:00
|
|
|
if (E->getDecl() != E->getFoundDecl())
|
2016-04-06 17:06:00 +00: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-01 23:48:14 +00:00
|
|
|
|
2012-01-27 09:46:47 +00:00
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
2015-12-29 18:15:14 +00:00
|
|
|
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
2011-03-06 18:19:42 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getDecl());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_DECL_REF;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddAPInt(E->getValue());
|
2011-06-03 02:27:19 +00:00
|
|
|
|
|
|
|
if (E->getValue().getBitWidth() == 32) {
|
|
|
|
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_INTEGER_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2018-06-20 17:19:40 +00:00
|
|
|
void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2020-04-07 14:46:08 -05:00
|
|
|
Record.push_back(E->getScale());
|
2018-06-20 17:19:40 +00:00
|
|
|
Record.AddAPInt(E->getValue());
|
2020-04-07 14:46:08 -05:00
|
|
|
Code = serialization::EXPR_FIXEDPOINT_LITERAL;
|
2018-06-20 17:19:40 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2013-01-22 09:46:51 +00:00
|
|
|
Record.push_back(E->getRawSemantics());
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(E->isExact());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddAPFloat(E->getValue());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_FLOATING_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_IMAGINARY_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2018-11-15 17:31:16 +00:00
|
|
|
|
|
|
|
// Store the various bits of data of StringLiteral.
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(E->getNumConcatenated());
|
2018-11-15 17:31:16 +00:00
|
|
|
Record.push_back(E->getLength());
|
|
|
|
Record.push_back(E->getCharByteWidth());
|
2023-11-05 12:27:31 +03:00
|
|
|
Record.push_back(llvm::to_underlying(E->getKind()));
|
2011-04-14 00:40:03 +00:00
|
|
|
Record.push_back(E->isPascal());
|
2018-11-15 17:31:16 +00:00
|
|
|
|
|
|
|
// Store the trailing array of SourceLocation.
|
2009-04-27 06:20:01 +00:00
|
|
|
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getStrTokenLoc(I));
|
2018-11-15 17:31:16 +00: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-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_STRING_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2023-11-05 13:35:38 +03:00
|
|
|
Record.push_back(llvm::to_underlying(E->getKind()));
|
2011-06-03 02:27:19 +00:00
|
|
|
|
|
|
|
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CHARACTER_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLParen());
|
|
|
|
Record.AddSourceLocation(E->getRParen());
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_PAREN;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
|
2010-06-30 08:49:18 +00:00
|
|
|
VisitExpr(E);
|
2018-11-20 16:20:40 +00:00
|
|
|
Record.push_back(E->getNumExprs());
|
|
|
|
for (auto *SubStmt : E->exprs())
|
|
|
|
Record.AddStmt(SubStmt);
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_PAREN_LIST;
|
2010-06-30 08:49:18 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2020-05-01 10:32:06 -07:00
|
|
|
bool HasFPFeatures = E->hasStoredFPFeatures();
|
|
|
|
// Write this first for easy access when deserializing, as they affect the
|
|
|
|
// size of the UnaryOperator.
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(HasFPFeatures);
|
2018-04-16 08:31:08 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBits(E->getOpcode(),
|
|
|
|
/*Width=*/5); // FIXME: stable encoding
|
2018-04-16 08:31:08 +00:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->canOverflow());
|
|
|
|
|
2020-05-01 10:32:06 -07:00
|
|
|
if (HasFPFeatures)
|
|
|
|
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
|
2018-04-16 08:31:08 +00:00
|
|
|
Code = serialization::EXPR_UNARY_OPERATOR;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00: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-28 22:16:22 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumComponents());
|
|
|
|
Record.push_back(E->getNumExpressions());
|
2016-04-06 17:06:00 +00: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-28 22:16:22 +00:00
|
|
|
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
2015-12-29 22:31:18 +00: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-28 22:16:22 +00:00
|
|
|
Record.push_back(ON.getKind()); // FIXME: Stable encoding
|
2016-04-06 17:06:00 +00: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-28 22:16:22 +00:00
|
|
|
switch (ON.getKind()) {
|
2015-12-29 22:31:18 +00: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-28 22:16:22 +00:00
|
|
|
Record.push_back(ON.getArrayExprIndex());
|
|
|
|
break;
|
2015-12-29 22:31:18 +00:00
|
|
|
|
|
|
|
case OffsetOfNode::Field:
|
2016-04-06 17:06:00 +00: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-28 22:16:22 +00:00
|
|
|
break;
|
2015-12-29 22:31:18 +00:00
|
|
|
|
|
|
|
case OffsetOfNode::Identifier:
|
2016-04-06 17:06:00 +00: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-28 22:16:22 +00:00
|
|
|
break;
|
2015-12-29 22:31:18 +00:00
|
|
|
|
|
|
|
case OffsetOfNode::Base:
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddCXXBaseSpecifier(*ON.getBase());
|
2010-04-29 00:18:15 +00: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-28 22:16:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getIndexExpr(I));
|
2010-08-18 23:57:32 +00: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-28 22:16:22 +00:00
|
|
|
}
|
|
|
|
|
2011-03-11 19:24:49 +00:00
|
|
|
void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2011-03-11 19:24:49 +00:00
|
|
|
Record.push_back(E->getKind());
|
2009-04-27 06:20:01 +00:00
|
|
|
if (E->isArgumentType())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
|
2009-04-27 06:20:01 +00:00
|
|
|
else {
|
|
|
|
Record.push_back(0);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getArgumentExpr());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_SIZEOF_ALIGN_OF;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
2009-04-27 06:20:01 +00: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-01 19:42:03 +01: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 14:24:04 +00:00
|
|
|
void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getLowerBound());
|
|
|
|
Record.AddStmt(E->getLength());
|
2020-07-09 13:27:32 -05:00
|
|
|
Record.AddStmt(E->getStride());
|
|
|
|
Record.AddSourceLocation(E->getColonLocFirst());
|
|
|
|
Record.AddSourceLocation(E->getColonLocSecond());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2015-08-25 14:24:04 +00: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 09:33:05 -05: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-01 15:06:38 -04: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 11:21:43 -04: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-01 15:06:38 -04:00
|
|
|
}
|
|
|
|
Code = serialization::EXPR_OMP_ITERATOR;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2023-12-07 17:01:06 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(E->getNumArgs());
|
|
|
|
CurrentPackingBits.updateBits();
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(static_cast<bool>(E->getADLCallKind()));
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.addBit(E->hasStoredFPFeatures());
|
2023-12-07 17:01:06 +08:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddStmt(E->getCallee());
|
2009-04-27 06:20:01 +00:00
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
|
|
Arg != ArgEnd; ++Arg)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(*Arg);
|
2023-12-07 17:01:06 +08:00
|
|
|
|
2020-07-24 12:04:19 +07:00
|
|
|
if (E->hasStoredFPFeatures())
|
|
|
|
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
|
|
|
|
E->getStmtClass() == Stmt::CallExprClass)
|
2023-12-21 10:30:12 +08:00
|
|
|
AbbrevToUse = Writer.getCallExprAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CALL;
|
2009-04-27 06:20:01 +00: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 16:30:40 +01: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-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
2019-06-06 23:24:15 +00:00
|
|
|
VisitExpr(E);
|
2019-06-05 11:46:57 +00:00
|
|
|
|
2019-06-06 23:24:15 +00:00
|
|
|
bool HasQualifier = E->hasQualifier();
|
2024-04-02 10:27:18 -04:00
|
|
|
bool HasFoundDecl = E->hasFoundDecl();
|
2019-06-06 23:24:15 +00:00
|
|
|
bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
|
|
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
|
|
|
|
|
|
// Write these first for easy access when deserializing, as they affect the
|
|
|
|
// size of the MemberExpr.
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(HasQualifier);
|
|
|
|
CurrentPackingBits.addBit(HasFoundDecl);
|
|
|
|
CurrentPackingBits.addBit(HasTemplateInfo);
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(NumTemplateArgs);
|
2019-06-05 11:46:57 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddDeclRef(E->getMemberDecl());
|
2019-06-06 23:24:15 +00:00
|
|
|
Record.AddDeclarationNameLoc(E->MemberDNLoc,
|
|
|
|
E->getMemberDecl()->getDeclName());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getMemberLoc());
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->isArrow());
|
|
|
|
CurrentPackingBits.addBit(E->hadMultipleCandidates());
|
|
|
|
CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2019-06-06 23:24:15 +00:00
|
|
|
|
2024-04-02 10:27:18 -04:00
|
|
|
if (HasQualifier)
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
|
2019-06-06 23:24:15 +00:00
|
|
|
if (HasFoundDecl) {
|
|
|
|
DeclAccessPair FoundDecl = E->getFoundDecl();
|
|
|
|
Record.AddDeclRef(FoundDecl.getDecl());
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
|
2019-06-06 23:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (HasTemplateInfo)
|
|
|
|
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
|
|
|
|
2015-05-01 02:04:32 +00:00
|
|
|
Code = serialization::EXPR_MEMBER;
|
2009-07-24 17:54:45 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
|
2009-07-24 17:54:45 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddSourceLocation(E->getIsaMemberLoc());
|
|
|
|
Record.AddSourceLocation(E->getOpLoc());
|
2009-07-24 17:54:45 +00:00
|
|
|
Record.push_back(E->isArrow());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_ISA;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2011-06-15 23:02:42 +00:00
|
|
|
void ASTStmtWriter::
|
|
|
|
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2011-06-15 23:02:42 +00:00
|
|
|
Record.push_back(E->shouldCopy());
|
|
|
|
Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
|
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getBridgeKeywordLoc());
|
2011-06-15 23:02:42 +00:00
|
|
|
Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
|
|
|
|
Code = serialization::EXPR_OBJC_BRIDGED_CAST;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2010-08-07 06:22:56 +00:00
|
|
|
Record.push_back(E->path_size());
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
2023-12-21 10:30:12 +08:00
|
|
|
// 7 bits should be enough to store the casting kinds.
|
|
|
|
CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7);
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.addBit(E->hasStoredFPFeatures());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-07 06:22:56 +00:00
|
|
|
|
|
|
|
for (CastExpr::path_iterator
|
|
|
|
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddCXXBaseSpecifier(**PI);
|
2020-09-12 21:54:14 +07:00
|
|
|
|
|
|
|
if (E->hasStoredFPFeatures())
|
|
|
|
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2023-12-21 16:35:20 +08:00
|
|
|
|
2020-04-10 13:34:46 -07:00
|
|
|
// Write this first for easy access when deserializing, as they affect the
|
|
|
|
// size of the UnaryOperator.
|
2023-12-21 16:35:20 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6);
|
2023-12-21 16:35:20 +08:00
|
|
|
bool HasFPFeatures = E->hasStoredFPFeatures();
|
|
|
|
CurrentPackingBits.addBit(HasFPFeatures);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2020-04-10 13:34:46 -07:00
|
|
|
if (HasFPFeatures)
|
|
|
|
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
if (!HasFPFeatures && E->getValueKind() == VK_PRValue &&
|
|
|
|
E->getObjectKind() == OK_Ordinary)
|
2023-12-21 10:30:12 +08:00
|
|
|
AbbrevToUse = Writer.getBinaryOperatorAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_BINARY_OPERATOR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitBinaryOperator(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeRef(E->getComputationLHSType());
|
|
|
|
Record.AddTypeRef(E->getComputationResultType());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
if (!E->hasStoredFPFeatures() && E->getValueKind() == VK_PRValue &&
|
|
|
|
E->getObjectKind() == OK_Ordinary)
|
2023-12-21 10:30:12 +08:00
|
|
|
AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getCond());
|
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getQuestionLoc());
|
|
|
|
Record.AddSourceLocation(E->getColonLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CONDITIONAL_OPERATOR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2011-02-17 10:25:35 +00:00
|
|
|
void
|
|
|
|
ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00: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 10:25:35 +00:00
|
|
|
Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitCastExpr(E);
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->isPartOfExplicitCast());
|
2014-07-27 04:19:32 +00:00
|
|
|
|
2020-09-12 21:54:14 +07:00
|
|
|
if (E->path_size() == 0 && !E->hasStoredFPFeatures())
|
2014-07-27 04:19:32 +00:00
|
|
|
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_IMPLICIT_CAST;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitCastExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CSTYLE_CAST;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddStmt(E->getInitializer());
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(E->isFileScope());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_COMPOUND_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddIdentifierRef(&E->getAccessor());
|
|
|
|
Record.AddSourceLocation(E->getAccessorLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2012-11-08 18:41:43 +00:00
|
|
|
// NOTE: only add the (possibly null) syntactic form.
|
|
|
|
// No need to serialize the isSemanticForm flag and the semantic form.
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSyntacticForm());
|
|
|
|
Record.AddSourceLocation(E->getLBraceLoc());
|
|
|
|
Record.AddSourceLocation(E->getRBraceLoc());
|
2011-04-21 00:27:41 +00:00
|
|
|
bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
|
|
|
|
Record.push_back(isArrayFiller);
|
|
|
|
if (isArrayFiller)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getArrayFiller());
|
2011-04-21 00:27:41 +00:00
|
|
|
else
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getInitializedFieldInUnion());
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(E->hadArrayRangeDesignator());
|
2011-04-22 05:29:30 +00: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-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
|
2011-04-22 05:29:30 +00:00
|
|
|
} else {
|
|
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getInit(I));
|
2011-04-22 05:29:30 +00:00
|
|
|
}
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_INIT_LIST;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSubExprs());
|
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr(I));
|
|
|
|
Record.AddSourceLocation(E->getEqualOrColonLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(E->usesGNUSyntax());
|
2023-03-02 12:08:07 -08:00
|
|
|
for (const DesignatedInitExpr::Designator &D : E->designators()) {
|
2016-06-23 00:15:04 +00:00
|
|
|
if (D.isFieldDesignator()) {
|
2023-04-17 16:31:42 -07:00
|
|
|
if (FieldDecl *Field = D.getFieldDecl()) {
|
2010-08-18 23:57:32 +00:00
|
|
|
Record.push_back(serialization::DESIG_FIELD_DECL);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(Field);
|
2009-04-27 06:20:01 +00:00
|
|
|
} else {
|
2010-08-18 23:57:32 +00:00
|
|
|
Record.push_back(serialization::DESIG_FIELD_NAME);
|
2016-06-23 00:15:04 +00:00
|
|
|
Record.AddIdentifierRef(D.getFieldName());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
2016-06-23 00:15:04 +00:00
|
|
|
Record.AddSourceLocation(D.getDotLoc());
|
|
|
|
Record.AddSourceLocation(D.getFieldLoc());
|
|
|
|
} else if (D.isArrayDesignator()) {
|
2010-08-18 23:57:32 +00:00
|
|
|
Record.push_back(serialization::DESIG_ARRAY);
|
2023-04-04 16:17:52 -07:00
|
|
|
Record.push_back(D.getArrayIndex());
|
2016-06-23 00:15:04 +00:00
|
|
|
Record.AddSourceLocation(D.getLBracketLoc());
|
|
|
|
Record.AddSourceLocation(D.getRBracketLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
} else {
|
2016-06-23 00:15:04 +00:00
|
|
|
assert(D.isArrayRangeDesignator() && "Unknown designator");
|
2010-08-18 23:57:32 +00:00
|
|
|
Record.push_back(serialization::DESIG_ARRAY_RANGE);
|
2023-04-04 16:17:52 -07:00
|
|
|
Record.push_back(D.getArrayIndex());
|
2016-06-23 00:15:04 +00:00
|
|
|
Record.AddSourceLocation(D.getLBracketLoc());
|
|
|
|
Record.AddSourceLocation(D.getEllipsisLoc());
|
|
|
|
Record.AddSourceLocation(D.getRBracketLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
}
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_DESIGNATED_INIT;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 00:27:52 +00:00
|
|
|
void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getUpdater());
|
2015-06-10 00:27:52 +00:00
|
|
|
Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Code = serialization::EXPR_NO_INIT;
|
|
|
|
}
|
|
|
|
|
2016-12-12 02:53:20 +00: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-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2015-09-17 20:55:33 +00:00
|
|
|
Record.push_back(E->isMicrosoftABI());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_VA_ARG;
|
2009-04-27 06:20:01 +00: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-16 21:04:15 +00:00
|
|
|
void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
|
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
2023-11-04 12:42:54 +03:00
|
|
|
Record.push_back(llvm::to_underlying(E->getIdentKind()));
|
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-16 21:04:15 +00:00
|
|
|
Code = serialization::EXPR_SOURCE_LOC;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getAmpAmpLoc());
|
|
|
|
Record.AddSourceLocation(E->getLabelLoc());
|
|
|
|
Record.AddDeclRef(E->getLabel());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_ADDR_LABEL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubStmt());
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2020-03-09 17:34:33 -07:00
|
|
|
Record.push_back(E->getTemplateDepth());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_STMT;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getCond());
|
|
|
|
Record.AddStmt(E->getLHS());
|
|
|
|
Record.AddStmt(E->getRHS());
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2013-07-20 00:40:58 +00:00
|
|
|
Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CHOOSE;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getTokenLocation());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_GNU_NULL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSubExprs());
|
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getExpr(I));
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_SHUFFLE_VECTOR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2013-09-18 03:29:45 +00:00
|
|
|
void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddStmt(E->getSrcExpr());
|
2013-09-18 03:29:45 +00:00
|
|
|
Code = serialization::EXPR_CONVERT_VECTOR;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getBlockDecl());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_BLOCK;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2011-04-15 00:35:48 +00:00
|
|
|
void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
|
|
|
|
VisitExpr(E);
|
2019-01-26 14:15:10 +00:00
|
|
|
|
2011-04-15 00:35:48 +00:00
|
|
|
Record.push_back(E->getNumAssocs());
|
2023-06-05 11:03:14 -04:00
|
|
|
Record.push_back(E->isExprPredicate());
|
2019-01-26 13:58:15 +00:00
|
|
|
Record.push_back(E->ResultIndex);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getGenericLoc());
|
|
|
|
Record.AddSourceLocation(E->getDefaultLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2019-01-26 14:15:10 +00: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 00:35:48 +00:00
|
|
|
Code = serialization::EXPR_GENERIC_SELECTION;
|
|
|
|
}
|
|
|
|
|
2011-11-06 09:01:30 +00: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-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSyntacticForm());
|
2011-11-06 09:01:30 +00:00
|
|
|
for (PseudoObjectExpr::semantics_iterator
|
|
|
|
i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(*i);
|
2011-11-06 09:01:30 +00:00
|
|
|
}
|
2011-11-15 06:20:27 +00:00
|
|
|
Code = serialization::EXPR_PSEUDO_OBJECT;
|
2011-11-06 09:01:30 +00:00
|
|
|
}
|
|
|
|
|
2011-10-11 02:20:01 +00:00
|
|
|
void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getOp());
|
2012-04-10 22:49:28 +00:00
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExprs()[I]);
|
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2011-11-15 06:20:27 +00:00
|
|
|
Code = serialization::EXPR_ATOMIC;
|
2011-10-11 02:20:01 +00:00
|
|
|
}
|
|
|
|
|
2009-04-27 06:20:01 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Objective-C Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getString());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_STRING_LITERAL;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2012-04-19 00:25:12 +00:00
|
|
|
void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
2012-03-06 20:05:56 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
|
|
Record.AddDeclRef(E->getBoxingMethod());
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-04-19 00:25:12 +00:00
|
|
|
Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
|
2012-03-06 20:05:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumElements());
|
|
|
|
for (unsigned i = 0; i < E->getNumElements(); i++)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getElement(i));
|
|
|
|
Record.AddDeclRef(E->getArrayWithObjectsMethod());
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-03-06 20:05:56 +00: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-06 17:06:00 +00:00
|
|
|
Record.AddStmt(Element.Key);
|
|
|
|
Record.AddStmt(Element.Value);
|
2012-03-06 20:05:56 +00:00
|
|
|
if (E->HasPackExpansions) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(Element.EllipsisLoc);
|
2012-03-06 20:05:56 +00:00
|
|
|
unsigned NumExpansions = 0;
|
|
|
|
if (Element.NumExpansions)
|
|
|
|
NumExpansions = *Element.NumExpansions + 1;
|
|
|
|
Record.push_back(NumExpansions);
|
|
|
|
}
|
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getDictWithObjectsMethod());
|
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-03-06 20:05:56 +00:00
|
|
|
Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_ENCODE;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSelectorRef(E->getSelector());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getProtocol());
|
|
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
|
|
Record.AddSourceLocation(E->ProtoLoc);
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getDecl());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddSourceLocation(E->getOpLoc());
|
|
|
|
Record.AddStmt(E->getBase());
|
2009-04-27 06:20:01 +00:00
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Record.push_back(E->isFreeIvar());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
2012-03-30 00:19:18 +00:00
|
|
|
Record.push_back(E->SetterAndMethodRefFlags.getInt());
|
2010-12-02 01:19:52 +00:00
|
|
|
Record.push_back(E->isImplicitProperty());
|
|
|
|
if (E->isImplicitProperty()) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getImplicitPropertyGetter());
|
|
|
|
Record.AddDeclRef(E->getImplicitPropertySetter());
|
2010-12-02 01:19:52 +00:00
|
|
|
} else {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getExplicitProperty());
|
2010-12-02 01:19:52 +00:00
|
|
|
}
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddSourceLocation(E->getReceiverLocation());
|
2010-12-02 01:19:52 +00:00
|
|
|
if (E->isObjectReceiver()) {
|
|
|
|
Record.push_back(0);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
2010-12-02 01:19:52 +00:00
|
|
|
} else if (E->isSuperReceiver()) {
|
|
|
|
Record.push_back(1);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeRef(E->getSuperReceiverType());
|
2010-12-02 01:19:52 +00:00
|
|
|
} else {
|
|
|
|
Record.push_back(2);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getClassReceiver());
|
2010-12-02 01:19:52 +00:00
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2012-03-06 20:05:56 +00:00
|
|
|
void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getRBracket());
|
|
|
|
Record.AddStmt(E->getBaseExpr());
|
|
|
|
Record.AddStmt(E->getKeyExpr());
|
|
|
|
Record.AddDeclRef(E->getAtIndexMethodDecl());
|
|
|
|
Record.AddDeclRef(E->setAtIndexMethodDecl());
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2012-03-06 20:05:56 +00:00
|
|
|
Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumArgs());
|
2011-10-03 06:36:51 +00:00
|
|
|
Record.push_back(E->getNumStoredSelLocs());
|
|
|
|
Record.push_back(E->SelLocsKind);
|
2011-06-15 23:02:42 +00:00
|
|
|
Record.push_back(E->isDelegateInitCall());
|
2012-01-12 02:34:39 +00: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 00:45:42 +00:00
|
|
|
Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
|
|
|
|
switch (E->getReceiverKind()) {
|
|
|
|
case ObjCMessageExpr::Instance:
|
2016-04-06 17:06:00 +00: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 00:45:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::Class:
|
2016-04-06 17:06:00 +00: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 00:45:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ObjCMessageExpr::SuperClass:
|
|
|
|
case ObjCMessageExpr::SuperInstance:
|
2016-04-06 17:06:00 +00: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 00:45:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (E->getMethodDecl()) {
|
|
|
|
Record.push_back(1);
|
2016-04-06 17:06:00 +00: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 00:45:42 +00:00
|
|
|
} else {
|
|
|
|
Record.push_back(0);
|
2018-07-30 19:24:48 +00: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 00:45:42 +00:00
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLeftLoc());
|
|
|
|
Record.AddSourceLocation(E->getRightLoc());
|
2009-04-27 06:20:01 +00:00
|
|
|
|
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
|
|
Arg != ArgEnd; ++Arg)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(*Arg);
|
2011-10-03 06:36:51 +00:00
|
|
|
|
|
|
|
SourceLocation *Locs = E->getStoredSelLocs();
|
|
|
|
for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(Locs[i]);
|
2011-10-03 06:36:51 +00:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getElement());
|
|
|
|
Record.AddStmt(S->getCollection());
|
|
|
|
Record.AddStmt(S->getBody());
|
|
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_OBJC_FOR_COLLECTION;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
2019-03-12 21:31:00 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getCatchBody());
|
|
|
|
Record.AddDeclRef(S->getCatchParamDecl());
|
|
|
|
Record.AddSourceLocation(S->getAtCatchLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_OBJC_CATCH;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
2019-03-12 21:31:00 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getFinallyBody());
|
|
|
|
Record.AddSourceLocation(S->getAtFinallyLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_OBJC_FINALLY;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2011-06-15 23:02:42 +00:00
|
|
|
void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
|
2019-03-12 21:31:00 +00:00
|
|
|
VisitStmt(S); // FIXME: no test coverage.
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getSubStmt());
|
|
|
|
Record.AddSourceLocation(S->getAtLoc());
|
2011-06-15 23:02:42 +00:00
|
|
|
Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
|
2019-03-12 21:31:00 +00:00
|
|
|
VisitStmt(S);
|
2010-04-23 22:50:49 +00:00
|
|
|
Record.push_back(S->getNumCatchStmts());
|
2014-05-22 05:54:18 +00:00
|
|
|
Record.push_back(S->getFinallyStmt() != nullptr);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getTryBody());
|
2021-10-26 10:53:33 -04:00
|
|
|
for (ObjCAtCatchStmt *C : S->catch_stmts())
|
|
|
|
Record.AddStmt(C);
|
2010-04-23 22:50:49 +00:00
|
|
|
if (S->getFinallyStmt())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getFinallyStmt());
|
|
|
|
Record.AddSourceLocation(S->getAtTryLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_OBJC_AT_TRY;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
|
2019-03-12 21:31:00 +00:00
|
|
|
VisitStmt(S); // FIXME: no test coverage.
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getSynchExpr());
|
|
|
|
Record.AddStmt(S->getSynchBody());
|
|
|
|
Record.AddSourceLocation(S->getAtSynchronizedLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
|
2019-03-12 21:31:00 +00:00
|
|
|
VisitStmt(S); // FIXME: no test coverage.
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getThrowExpr());
|
|
|
|
Record.AddSourceLocation(S->getThrowLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_OBJC_AT_THROW;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2012-03-06 20:05:56 +00:00
|
|
|
void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2012-03-06 20:05:56 +00:00
|
|
|
Code = serialization::EXPR_OBJC_BOOL_LITERAL;
|
|
|
|
}
|
|
|
|
|
2016-07-16 00:35:23 +00: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 03:19:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
|
2010-07-22 16:03:56 +00:00
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getCatchLoc());
|
|
|
|
Record.AddDeclRef(S->getExceptionDecl());
|
|
|
|
Record.AddStmt(S->getHandlerBlock());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_CXX_CATCH;
|
2010-07-22 16:03:56 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
|
2010-07-22 16:03:56 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getNumHandlers());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getTryLoc());
|
|
|
|
Record.AddStmt(S->getTryBlock());
|
2010-07-22 16:03:56 +00:00
|
|
|
for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(S->getHandler(i));
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::STMT_CXX_TRY;
|
2010-07-22 16:03:56 +00:00
|
|
|
}
|
|
|
|
|
2011-04-14 22:09:26 +00:00
|
|
|
void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
|
|
Record.AddSourceLocation(S->getCoawaitLoc());
|
|
|
|
Record.AddSourceLocation(S->getColonLoc());
|
|
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
2018-09-28 18:44:09 +00:00
|
|
|
Record.AddStmt(S->getInit());
|
2016-04-06 17:06:00 +00: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-14 22:09:26 +00:00
|
|
|
Code = serialization::STMT_CXX_FOR_RANGE;
|
|
|
|
}
|
|
|
|
|
2011-10-25 01:33:02 +00:00
|
|
|
void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
2011-10-25 01:33:02 +00:00
|
|
|
Record.push_back(S->isIfExists());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
|
|
|
|
Record.AddDeclarationNameInfo(S->getNameInfo());
|
|
|
|
Record.AddStmt(S->getSubStmt());
|
2011-10-25 01:33:02 +00:00
|
|
|
Code = serialization::STMT_MS_DEPENDENT_EXISTS;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
|
2009-07-14 03:19:21 +00:00
|
|
|
VisitCallExpr(E);
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(E->getOperator());
|
2020-06-26 08:45:12 -07:00
|
|
|
Record.AddSourceRange(E->Range);
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
|
2023-12-21 10:30:12 +08:00
|
|
|
AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_OPERATOR_CALL;
|
2009-07-14 03:19:21 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
2010-05-09 05:36:05 +00:00
|
|
|
VisitCallExpr(E);
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
|
2023-12-21 10:30:12 +08:00
|
|
|
AbbrevToUse = Writer.getCXXMemberCallExprAbbrev();
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_MEMBER_CALL;
|
2010-05-09 05:36:05 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 00:04:38 +00: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-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
2009-09-09 23:08:42 +00:00
|
|
|
VisitExpr(E);
|
2018-12-22 14:39:30 +00:00
|
|
|
|
2010-06-24 08:57:09 +00:00
|
|
|
Record.push_back(E->getNumArgs());
|
2009-09-09 23:08:42 +00:00
|
|
|
Record.push_back(E->isElidable());
|
2011-10-05 07:56:41 +00:00
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
2012-12-19 01:39:02 +00:00
|
|
|
Record.push_back(E->isListInitialization());
|
2014-07-17 05:12:35 +00:00
|
|
|
Record.push_back(E->isStdInitListInitialization());
|
2009-12-16 18:50:27 +00:00
|
|
|
Record.push_back(E->requiresZeroInitialization());
|
2023-11-05 16:38:10 +03:00
|
|
|
Record.push_back(
|
|
|
|
llvm::to_underlying(E->getConstructionKind())); // FIXME: stable encoding
|
2023-05-08 12:18:43 +02:00
|
|
|
Record.push_back(E->isImmediateEscalating());
|
2018-12-22 14:39:30 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
|
|
Record.AddDeclRef(E->getConstructor());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getParenOrBraceRange());
|
2018-12-22 14:39:30 +00:00
|
|
|
|
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
|
|
Record.AddStmt(E->getArg(I));
|
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_CONSTRUCT;
|
2009-09-09 23:08:42 +00: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-28 19:03:57 +00: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-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
|
2010-07-10 11:46:15 +00:00
|
|
|
VisitCXXConstructExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
|
2010-07-10 11:46:15 +00:00
|
|
|
}
|
|
|
|
|
2012-02-07 10:09:13 +00:00
|
|
|
void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
|
|
|
|
VisitExpr(E);
|
2020-06-13 14:17:03 +01:00
|
|
|
Record.push_back(E->LambdaExprBits.NumCaptures);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->IntroducerRange);
|
2020-06-13 14:17:03 +01:00
|
|
|
Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->CaptureDefaultLoc);
|
2020-06-13 14:17:03 +01:00
|
|
|
Record.push_back(E->LambdaExprBits.ExplicitParams);
|
|
|
|
Record.push_back(E->LambdaExprBits.ExplicitResultType);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->ClosingBrace);
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2012-02-14 17:54:36 +00:00
|
|
|
// Add capture initializers.
|
|
|
|
for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
|
|
|
|
CEnd = E->capture_init_end();
|
|
|
|
C != CEnd; ++C) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(*C);
|
2012-02-14 17:54:36 +00:00
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2020-07-02 14:13:35 +01:00
|
|
|
// Don't serialize the body. It belongs to the call operator declaration.
|
|
|
|
// LambdaExpr only stores a copy of the Stmt *.
|
2020-06-18 12:51:11 +01:00
|
|
|
|
2012-02-14 17:54:36 +00:00
|
|
|
Code = serialization::EXPR_LAMBDA;
|
2012-02-07 10:09:13 +00:00
|
|
|
}
|
|
|
|
|
2013-06-12 22:31:48 +00:00
|
|
|
void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2013-06-12 22:31:48 +00:00
|
|
|
Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
2010-01-16 21:21:01 +00:00
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->getAngleBrackets().isValid());
|
|
|
|
if (E->getAngleBrackets().isValid())
|
|
|
|
Record.AddSourceRange(E->getAngleBrackets());
|
2010-01-16 21:21:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
|
2010-01-16 21:21:01 +00:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_STATIC_CAST;
|
2010-01-16 21:21:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
|
2010-01-16 21:21:01 +00:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_DYNAMIC_CAST;
|
2010-01-16 21:21:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
|
2010-01-16 21:21:01 +00:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_REINTERPRET_CAST;
|
2010-01-16 21:21:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
2010-01-16 21:21:01 +00:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_CONST_CAST;
|
2010-01-16 21:21:01 +00:00
|
|
|
}
|
|
|
|
|
2020-05-18 11:02:01 +01:00
|
|
|
void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
|
|
|
|
VisitCXXNamedCastExpr(E);
|
|
|
|
Code = serialization::EXPR_CXX_ADDRSPACE_CAST;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
2010-01-16 21:21:01 +00:00
|
|
|
VisitExplicitCastExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
2010-01-16 21:21:01 +00:00
|
|
|
}
|
|
|
|
|
2019-07-02 18:28:13 +00:00
|
|
|
void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) {
|
|
|
|
VisitExplicitCastExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
2020-06-11 12:30:16 -04:00
|
|
|
Code = serialization::EXPR_BUILTIN_BIT_CAST;
|
2019-07-02 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
2012-03-07 08:35:16 +00:00
|
|
|
void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
|
|
|
|
VisitCallExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->UDSuffixLoc);
|
2012-03-07 08:35:16 +00:00
|
|
|
Code = serialization::EXPR_USER_DEFINED_LITERAL;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
2010-02-07 06:32:43 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_BOOL_LITERAL;
|
2010-02-07 06:32:43 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
|
2010-02-07 06:32:43 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
|
2010-02-07 06:32:43 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
2010-05-09 06:03:39 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2010-05-09 06:03:39 +00:00
|
|
|
if (E->isTypeOperand()) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_TYPEID_TYPE;
|
2010-05-09 06:03:39 +00:00
|
|
|
} else {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getExprOperand());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_TYPEID_EXPR;
|
2010-05-09 06:03:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
|
2010-05-09 06:15:05 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2010-05-09 06:15:05 +00:00
|
|
|
Record.push_back(E->isImplicit());
|
2023-12-21 16:35:20 +08:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_THIS;
|
2010-05-09 06:15:05 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
|
2010-05-09 06:40:08 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getThrowLoc());
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2011-07-06 22:04:06 +00:00
|
|
|
Record.push_back(E->isThrownVariableInScope());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_THROW;
|
2010-05-09 06:15:05 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
2010-05-09 06:40:08 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00: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-16 21:04:15 +00:00
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getUsedLocation());
|
2022-10-23 17:32:58 +02:00
|
|
|
Record.push_back(E->hasRewrittenInit());
|
|
|
|
if (E->hasRewrittenInit())
|
|
|
|
Record.AddStmt(E->getRewrittenExpr());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_ARG;
|
2010-05-09 06:40:08 +00:00
|
|
|
}
|
|
|
|
|
2013-04-20 22:23:05 +00:00
|
|
|
void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
2022-10-23 17:32:58 +02:00
|
|
|
Record.push_back(E->hasRewrittenInit());
|
2016-04-06 17:06:00 +00: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-16 21:04:15 +00:00
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getExprLoc());
|
2022-10-23 17:32:58 +02:00
|
|
|
if (E->hasRewrittenInit())
|
|
|
|
Record.AddStmt(E->getRewrittenExpr());
|
2013-04-20 22:23:05 +00:00
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_INIT;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
2010-05-10 00:25:06 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddCXXTemporary(E->getTemporary());
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_BIND_TEMPORARY;
|
2010-05-10 00:25:06 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
2010-05-10 01:22:27 +00:00
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
|
2010-05-10 01:22:27 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
|
2010-05-10 01:22:27 +00:00
|
|
|
VisitExpr(E);
|
2019-01-07 15:04:45 +00:00
|
|
|
|
2012-02-16 11:35:52 +00:00
|
|
|
Record.push_back(E->isArray());
|
2019-01-07 15:04:45 +00:00
|
|
|
Record.push_back(E->hasInitializer());
|
|
|
|
Record.push_back(E->getNumPlacementArgs());
|
|
|
|
Record.push_back(E->isParenTypeId());
|
|
|
|
|
|
|
|
Record.push_back(E->isGlobalNew());
|
2016-10-10 18:54:32 +00:00
|
|
|
Record.push_back(E->passAlignment());
|
2012-02-16 12:22:20 +00:00
|
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
2024-01-22 00:42:50 +04:00
|
|
|
Record.push_back(E->CXXNewExprBits.HasInitializer);
|
2019-01-07 15:04:45 +00:00
|
|
|
Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getOperatorNew());
|
|
|
|
Record.AddDeclRef(E->getOperatorDelete());
|
|
|
|
Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
|
2019-01-07 15:04:45 +00:00
|
|
|
if (E->isParenTypeId())
|
|
|
|
Record.AddSourceRange(E->getTypeIdParens());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddSourceRange(E->getDirectInitRange());
|
2019-01-07 15:04:45 +00:00
|
|
|
|
|
|
|
for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
|
|
|
|
I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(*I);
|
2012-02-16 12:22:20 +00:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_NEW;
|
2010-05-10 01:22:27 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
2010-06-22 17:07:59 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isGlobalDelete());
|
|
|
|
Record.push_back(E->isArrayForm());
|
2010-09-13 20:15:54 +00:00
|
|
|
Record.push_back(E->isArrayFormAsWritten());
|
2011-01-27 09:37:56 +00:00
|
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getOperatorDelete());
|
|
|
|
Record.AddStmt(E->getArgument());
|
2018-12-03 12:32:32 +00:00
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_DELETE;
|
2010-06-22 17:07:59 +00:00
|
|
|
}
|
2010-05-10 01:22:27 +00:00
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
2010-06-28 09:32:03 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
2010-06-28 09:32:03 +00:00
|
|
|
Record.push_back(E->isArrow());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
Record.AddTypeSourceInfo(E->getScopeTypeInfo());
|
|
|
|
Record.AddSourceLocation(E->getColonColonLoc());
|
|
|
|
Record.AddSourceLocation(E->getTildeLoc());
|
2010-06-28 09:32:03 +00:00
|
|
|
|
|
|
|
// PseudoDestructorTypeStorage.
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
|
2010-06-28 09:32:03 +00:00
|
|
|
if (E->getDestroyedTypeIdentifier())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getDestroyedTypeLoc());
|
2010-06-28 09:32:03 +00:00
|
|
|
else
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());
|
2010-06-28 09:32:03 +00:00
|
|
|
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
|
2010-06-28 09:32:03 +00:00
|
|
|
}
|
|
|
|
|
2010-12-06 08:20:24 +00:00
|
|
|
void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
2010-05-10 00:25:06 +00:00
|
|
|
VisitExpr(E);
|
2011-11-10 05:35:25 +00:00
|
|
|
Record.push_back(E->getNumObjects());
|
2020-03-10 14:06:25 -07: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-21 20:29:17 +00:00
|
|
|
|
|
|
|
Record.push_back(E->cleanupsHaveSideEffects());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSubExpr());
|
2010-12-06 08:20:24 +00:00
|
|
|
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
2010-05-10 00:25:06 +00:00
|
|
|
}
|
|
|
|
|
2019-01-08 14:17:00 +00:00
|
|
|
void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
|
|
|
|
CXXDependentScopeMemberExpr *E) {
|
2010-06-24 08:57:31 +00:00
|
|
|
VisitExpr(E);
|
2012-01-27 09:46:47 +00:00
|
|
|
|
2019-01-08 14:17:00 +00:00
|
|
|
// Don't emit anything here (or if you do you will have to update
|
|
|
|
// the corresponding deserialization function).
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(E->getNumTemplateArgs());
|
|
|
|
CurrentPackingBits.updateBits();
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
|
|
|
|
CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope());
|
2010-06-24 08:57:31 +00:00
|
|
|
|
2019-01-08 14:17:00 +00:00
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2015-12-29 18:15:14 +00:00
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
|
|
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
|
|
|
AddTemplateKWAndArgsInfo(ArgInfo,
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
2010-06-24 08:57:31 +00:00
|
|
|
}
|
2012-01-27 09:46:47 +00:00
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->isArrow());
|
|
|
|
|
2019-01-08 14:17:00 +00:00
|
|
|
Record.AddTypeRef(E->getBaseType());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(!E->isImplicitAccess());
|
2023-12-15 14:30:24 -08:00
|
|
|
if (!E->isImplicitAccess())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2019-01-08 14:17:00 +00:00
|
|
|
|
|
|
|
if (E->hasFirstQualifierFoundInScope())
|
|
|
|
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclarationNameInfo(E->MemberNameInfo);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
|
2010-06-24 08:57:31 +00:00
|
|
|
}
|
|
|
|
|
2010-06-28 09:31:56 +00:00
|
|
|
void
|
2010-08-18 23:56:27 +00:00
|
|
|
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
|
2010-06-28 09:31:56 +00:00
|
|
|
VisitExpr(E);
|
2012-01-27 09:46:47 +00:00
|
|
|
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
2011-02-04 12:01:24 +00:00
|
|
|
// emitted first.
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(
|
|
|
|
E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
|
2012-01-27 09:46:47 +00:00
|
|
|
|
2019-01-07 14:27:04 +00:00
|
|
|
if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
|
2015-12-29 18:15:14 +00:00
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
|
|
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
2023-12-21 10:30:12 +08:00
|
|
|
// 16 bits should be enought to store the number of args
|
|
|
|
CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16);
|
2015-12-29 18:15:14 +00:00
|
|
|
AddTemplateKWAndArgsInfo(ArgInfo,
|
|
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
2010-06-28 09:31:56 +00:00
|
|
|
}
|
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
Record.AddDeclarationNameInfo(E->NameInfo);
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
|
2010-06-28 09:31:56 +00:00
|
|
|
}
|
|
|
|
|
2010-06-24 08:57:31 +00:00
|
|
|
void
|
2010-08-18 23:56:27 +00:00
|
|
|
ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
|
2010-06-24 08:57:31 +00:00
|
|
|
VisitExpr(E);
|
2020-10-30 16:49:24 +00:00
|
|
|
Record.push_back(E->getNumArgs());
|
2010-06-24 08:57:31 +00:00
|
|
|
for (CXXUnresolvedConstructExpr::arg_iterator
|
|
|
|
ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(*ArgI);
|
|
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
2023-04-14 07:18:46 -04:00
|
|
|
Record.push_back(E->isListInitialization());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
|
2010-06-24 08:57:31 +00:00
|
|
|
}
|
2010-05-09 06:15:05 +00:00
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
|
2010-06-25 09:03:26 +00:00
|
|
|
VisitExpr(E);
|
2012-01-27 09:46:47 +00:00
|
|
|
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(E->getNumDecls());
|
|
|
|
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.updateBits();
|
|
|
|
CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
|
2019-01-09 15:43:19 +00:00
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2015-12-29 18:15:14 +00:00
|
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
|
|
*E->getTrailingASTTemplateKWAndArgsInfo();
|
2023-12-21 16:35:20 +08:00
|
|
|
Record.push_back(ArgInfo.NumTemplateArgs);
|
2015-12-29 18:15:14 +00:00
|
|
|
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
|
2023-12-21 10:30:12 +08:00
|
|
|
}
|
2010-06-25 09:03:26 +00:00
|
|
|
|
2019-01-09 15:43:19 +00:00
|
|
|
for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
|
|
|
|
OvE = E->decls_end();
|
|
|
|
OvI != OvE; ++OvI) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(OvI.getDecl());
|
2010-06-25 09:03:26 +00:00
|
|
|
Record.push_back(OvI.getAccess());
|
|
|
|
}
|
|
|
|
|
2019-01-09 15:43:19 +00:00
|
|
|
Record.AddDeclarationNameInfo(E->getNameInfo());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
2010-06-25 09:03:26 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
|
2010-06-25 09:03:26 +00:00
|
|
|
VisitOverloadExpr(E);
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->isArrow());
|
|
|
|
CurrentPackingBits.addBit(E->hasUnresolvedUsing());
|
|
|
|
CurrentPackingBits.addBit(!E->isImplicitAccess());
|
|
|
|
if (!E->isImplicitAccess())
|
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
|
2023-12-15 14:30:24 -08:00
|
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
2023-12-21 10:30:12 +08:00
|
|
|
|
|
|
|
Record.AddTypeRef(E->getBaseType());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
|
2010-06-25 09:03:26 +00:00
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:27 +00:00
|
|
|
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
|
2010-06-25 09:03:34 +00:00
|
|
|
VisitOverloadExpr(E);
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->requiresADL());
|
|
|
|
CurrentPackingBits.addBit(E->isOverloaded());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getNamingClass());
|
2010-08-18 23:57:32 +00:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
|
2010-06-25 09:03:34 +00:00
|
|
|
}
|
|
|
|
|
2012-02-24 07:38:34 +00: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-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
2012-02-24 07:38:34 +00:00
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getArg(I));
|
2012-02-24 07:38:34 +00:00
|
|
|
Code = serialization::EXPR_TYPE_TRAIT;
|
|
|
|
}
|
|
|
|
|
2011-04-28 00:16:57 +00:00
|
|
|
void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getTrait());
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
|
2016-09-28 10:16:56 +00:00
|
|
|
Record.AddStmt(E->getDimensionExpression());
|
2011-04-28 00:16:57 +00:00
|
|
|
Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
|
|
|
|
}
|
|
|
|
|
2011-04-25 06:54:41 +00:00
|
|
|
void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getTrait());
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddStmt(E->getQueriedExpression());
|
2011-04-25 06:54:41 +00:00
|
|
|
Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
|
|
|
|
}
|
|
|
|
|
2010-09-10 20:55:54 +00:00
|
|
|
void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
|
|
Record.AddStmt(E->getOperand());
|
2010-09-10 20:55:54 +00:00
|
|
|
Code = serialization::EXPR_CXX_NOEXCEPT;
|
|
|
|
}
|
|
|
|
|
2011-01-03 17:17:50 +00:00
|
|
|
void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getEllipsisLoc());
|
2011-01-14 21:20:45 +00:00
|
|
|
Record.push_back(E->NumExpansions);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getPattern());
|
2011-01-03 17:17:50 +00:00
|
|
|
Code = serialization::EXPR_PACK_EXPANSION;
|
|
|
|
}
|
|
|
|
|
2011-01-04 17:33:58 +00:00
|
|
|
void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
2015-09-23 21:41:42 +00:00
|
|
|
Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
|
|
|
|
: 0);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->OperatorLoc);
|
|
|
|
Record.AddSourceLocation(E->PackLoc);
|
|
|
|
Record.AddSourceLocation(E->RParenLoc);
|
|
|
|
Record.AddDeclRef(E->Pack);
|
2015-09-23 21:41:42 +00:00
|
|
|
if (E->isPartiallySubstituted()) {
|
|
|
|
for (const auto &TA : E->getPartialArguments())
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTemplateArgument(TA);
|
2015-09-23 21:41:42 +00:00
|
|
|
} else if (!E->isValueDependent()) {
|
|
|
|
Record.push_back(E->getPackLength());
|
|
|
|
}
|
2011-01-04 17:33:58 +00:00
|
|
|
Code = serialization::EXPR_SIZEOF_PACK;
|
|
|
|
}
|
|
|
|
|
2024-01-27 10:23:38 +01:00
|
|
|
void ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->TransformedExpressions);
|
|
|
|
Record.AddSourceLocation(E->getEllipsisLoc());
|
|
|
|
Record.AddSourceLocation(E->getRSquareLoc());
|
|
|
|
Record.AddStmt(E->getPackIdExpression());
|
|
|
|
Record.AddStmt(E->getIndexExpr());
|
|
|
|
Record.push_back(E->TransformedExpressions);
|
|
|
|
for (Expr *Sub : E->getExpressions())
|
|
|
|
Record.AddStmt(Sub);
|
|
|
|
Code = serialization::EXPR_PACK_INDEXING;
|
|
|
|
}
|
|
|
|
|
2011-07-15 07:00:14 +00:00
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
|
|
|
|
SubstNonTypeTemplateParmExpr *E) {
|
|
|
|
VisitExpr(E);
|
2022-08-14 13:48:18 +02:00
|
|
|
Record.AddDeclRef(E->getAssociatedDecl());
|
2023-12-21 10:30:12 +08:00
|
|
|
CurrentPackingBits.addBit(E->isReferenceParameter());
|
|
|
|
CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12);
|
|
|
|
CurrentPackingBits.addBit((bool)E->getPackIndex());
|
2022-08-14 13:48:18 +02:00
|
|
|
if (auto PackIndex = E->getPackIndex())
|
|
|
|
Record.push_back(*PackIndex + 1);
|
2023-12-21 10:30:12 +08:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getNameLoc());
|
|
|
|
Record.AddStmt(E->getReplacement());
|
2011-07-15 07:00:14 +00:00
|
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
|
|
|
|
}
|
|
|
|
|
2011-01-15 01:15:58 +00:00
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
|
|
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
2022-08-14 13:48:18 +02:00
|
|
|
Record.AddDeclRef(E->getAssociatedDecl());
|
|
|
|
Record.push_back(E->getIndex());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTemplateArgument(E->getArgumentPack());
|
|
|
|
Record.AddSourceLocation(E->getParameterPackLocation());
|
2011-01-15 01:15:58 +00:00
|
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
|
|
|
|
}
|
|
|
|
|
2012-09-12 00:56:43 +00:00
|
|
|
void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumExpansions());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(E->getParameterPack());
|
|
|
|
Record.AddSourceLocation(E->getParameterPackLocation());
|
2012-09-12 00:56:43 +00:00
|
|
|
for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
|
|
|
|
I != End; ++I)
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclRef(*I);
|
2012-09-12 00:56:43 +00:00
|
|
|
Code = serialization::EXPR_FUNCTION_PARM_PACK;
|
|
|
|
}
|
|
|
|
|
2011-06-21 17:03:29 +00:00
|
|
|
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
|
|
|
VisitExpr(E);
|
2019-11-17 11:41:55 +01:00
|
|
|
Record.push_back(static_cast<bool>(E->getLifetimeExtendedTemporaryDecl()));
|
|
|
|
if (E->getLifetimeExtendedTemporaryDecl())
|
|
|
|
Record.AddDeclRef(E->getLifetimeExtendedTemporaryDecl());
|
|
|
|
else
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
2011-06-21 17:03:29 +00:00
|
|
|
Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
|
|
|
|
}
|
|
|
|
|
2014-11-08 05:07:16 +00:00
|
|
|
void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->LParenLoc);
|
|
|
|
Record.AddSourceLocation(E->EllipsisLoc);
|
|
|
|
Record.AddSourceLocation(E->RParenLoc);
|
2019-05-13 08:31:14 +00:00
|
|
|
Record.push_back(E->NumExpansions);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->SubExprs[0]);
|
|
|
|
Record.AddStmt(E->SubExprs[1]);
|
2020-08-06 15:57:35 -07:00
|
|
|
Record.AddStmt(E->SubExprs[2]);
|
2014-11-08 05:07:16 +00:00
|
|
|
Record.push_back(E->Opcode);
|
|
|
|
Code = serialization::EXPR_CXX_FOLD;
|
|
|
|
}
|
|
|
|
|
2023-01-04 15:12:00 -08:00
|
|
|
void ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
ArrayRef<Expr *> InitExprs = E->getInitExprs();
|
|
|
|
Record.push_back(InitExprs.size());
|
|
|
|
Record.push_back(E->getUserSpecifiedInitExprs().size());
|
|
|
|
Record.AddSourceLocation(E->getInitLoc());
|
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
for (Expr *InitExpr : E->getInitExprs())
|
|
|
|
Record.AddStmt(InitExpr);
|
|
|
|
Expr *ArrayFiller = E->getArrayFiller();
|
|
|
|
FieldDecl *UnionField = E->getInitializedFieldInUnion();
|
|
|
|
bool HasArrayFillerOrUnionDecl = ArrayFiller || UnionField;
|
|
|
|
Record.push_back(HasArrayFillerOrUnionDecl);
|
|
|
|
if (HasArrayFillerOrUnionDecl) {
|
|
|
|
Record.push_back(static_cast<bool>(ArrayFiller));
|
|
|
|
if (ArrayFiller)
|
|
|
|
Record.AddStmt(ArrayFiller);
|
|
|
|
else
|
|
|
|
Record.AddDeclRef(UnionField);
|
|
|
|
}
|
|
|
|
Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
|
|
|
|
}
|
|
|
|
|
2010-11-15 23:31:06 +00:00
|
|
|
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getSourceExpr());
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
2018-03-20 01:47:58 +00:00
|
|
|
Record.push_back(E->isUnique());
|
2010-11-15 23:31:06 +00:00
|
|
|
Code = serialization::EXPR_OPAQUE_VALUE;
|
|
|
|
}
|
|
|
|
|
2014-10-27 18:07:20 +00:00
|
|
|
void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
// TODO: Figure out sane writer behavior for a TypoExpr, if necessary
|
2016-01-30 08:03:54 +00:00
|
|
|
llvm_unreachable("Cannot write TypoExpr nodes");
|
2014-10-27 18:07:20 +00:00
|
|
|
}
|
|
|
|
|
2011-02-09 21:07:24 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CUDA Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
|
|
|
VisitCallExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getConfig());
|
2011-02-09 21:07:24 +00:00
|
|
|
Code = serialization::EXPR_CUDA_KERNEL_CALL;
|
|
|
|
}
|
|
|
|
|
2011-06-04 00:47:47 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenCL Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Record.AddStmt(E->getSrcExpr());
|
2011-06-04 00:47:47 +00:00
|
|
|
Code = serialization::EXPR_ASTYPE;
|
|
|
|
}
|
|
|
|
|
2011-07-15 07:00:14 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Microsoft Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-04-16 07:28:30 +00:00
|
|
|
void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isArrow());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBaseExpr());
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
Record.AddSourceLocation(E->getMemberLoc());
|
|
|
|
Record.AddDeclRef(E->getPropertyDecl());
|
2013-04-16 07:28:30 +00:00
|
|
|
Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
|
|
|
|
}
|
|
|
|
|
2015-11-25 12:01:00 +00:00
|
|
|
void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getBase());
|
|
|
|
Record.AddStmt(E->getIdx());
|
|
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
2015-11-25 12:01:00 +00:00
|
|
|
Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
|
|
|
|
}
|
|
|
|
|
2011-07-15 07:00:14 +00:00
|
|
|
void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
|
|
|
VisitExpr(E);
|
2016-04-06 17:06:00 +00: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-11 22:15:29 -07:00
|
|
|
Record.AddDeclRef(E->getGuidDecl());
|
2011-07-15 07:00:14 +00:00
|
|
|
if (E->isTypeOperand()) {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
|
2011-07-15 07:00:14 +00:00
|
|
|
Code = serialization::EXPR_CXX_UUIDOF_TYPE;
|
|
|
|
} else {
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddStmt(E->getExprOperand());
|
2011-07-15 07:00:14 +00:00
|
|
|
Code = serialization::EXPR_CXX_UUIDOF_EXPR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getExceptLoc());
|
|
|
|
Record.AddStmt(S->getFilterExpr());
|
|
|
|
Record.AddStmt(S->getBlock());
|
2011-07-15 07:00:14 +00:00
|
|
|
Code = serialization::STMT_SEH_EXCEPT;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getFinallyLoc());
|
|
|
|
Record.AddStmt(S->getBlock());
|
2011-07-15 07:00:14 +00:00
|
|
|
Code = serialization::STMT_SEH_FINALLY;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getIsCXXTry());
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getTryLoc());
|
|
|
|
Record.AddStmt(S->getTryBlock());
|
|
|
|
Record.AddStmt(S->getHandler());
|
2011-07-15 07:00:14 +00:00
|
|
|
Code = serialization::STMT_SEH_TRY;
|
|
|
|
}
|
|
|
|
|
2014-07-07 00:12:30 +00:00
|
|
|
void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
|
|
|
|
VisitStmt(S);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddSourceLocation(S->getLeaveLoc());
|
2014-07-07 00:12:30 +00:00
|
|
|
Code = serialization::STMT_SEH_LEAVE;
|
|
|
|
}
|
|
|
|
|
2013-07-19 03:13:43 +00: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-26 17:42:31 -04:00
|
|
|
|
2021-03-03 17:15:32 -06: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 03:13:43 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeOMPChildren(E->Data);
|
2018-08-09 21:08:08 +00:00
|
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
2018-08-09 21:09:38 +00:00
|
|
|
Record.AddSourceLocation(E->getEndLoc());
|
2023-08-09 14:26:29 -05:00
|
|
|
Record.writeEnum(E->getMappedDirective());
|
2013-07-19 03:13:43 +00:00
|
|
|
}
|
|
|
|
|
2021-02-12 11:26:59 -08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) {
|
2014-02-27 08:29:12 +00:00
|
|
|
VisitStmt(D);
|
2021-02-12 11:26:59 -08:00
|
|
|
Record.writeUInt32(D->getLoopsNumber());
|
2013-07-19 03:13:43 +00:00
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
}
|
|
|
|
|
2021-02-12 11:26:59 -08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
|
|
|
|
VisitOMPLoopBasedDirective(D);
|
|
|
|
}
|
|
|
|
|
2021-09-17 16:03:01 -05:00
|
|
|
void ASTStmtWriter::VisitOMPMetaDirective(OMPMetaDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_META_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-08-19 11:27:13 +00:00
|
|
|
void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
|
2014-02-27 08:29:12 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-08-19 11:27:13 +00:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
2014-02-27 08:29:12 +00:00
|
|
|
Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-10-06 10:02:27 -05:00
|
|
|
void ASTStmtWriter::VisitOMPLoopTransformationDirective(
|
|
|
|
OMPLoopTransformationDirective *D) {
|
2021-02-12 11:26:59 -08:00
|
|
|
VisitOMPLoopBasedDirective(D);
|
2021-10-06 11:43:29 -05:00
|
|
|
Record.writeUInt32(D->getNumGeneratedLoops());
|
2021-10-06 10:02:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) {
|
|
|
|
VisitOMPLoopTransformationDirective(D);
|
2021-02-12 11:26:59 -08:00
|
|
|
Code = serialization::STMT_OMP_TILE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-06-10 14:24:17 -05:00
|
|
|
void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
|
2021-10-06 10:02:27 -05:00
|
|
|
VisitOMPLoopTransformationDirective(D);
|
2021-06-10 14:24:17 -05:00
|
|
|
Code = serialization::STMT_OMP_UNROLL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-18 04:14:57 +00:00
|
|
|
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
|
2014-08-19 11:27:13 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-06-18 04:14:57 +00:00
|
|
|
Code = serialization::STMT_OMP_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-18 05:12:34 +00:00
|
|
|
void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-25 11:44:49 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-06-25 11:44:49 +00:00
|
|
|
Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-26 08:21:58 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-06-26 08:21:58 +00:00
|
|
|
Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2023-08-09 15:28:09 -07:00
|
|
|
void ASTStmtWriter::VisitOMPScopeDirective(OMPScopeDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SCOPE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-26 12:05:45 +00:00
|
|
|
void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-17 08:54:58 +00:00
|
|
|
void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 09:42:05 +00:00
|
|
|
void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
2016-04-06 17:06:00 +00:00
|
|
|
Record.AddDeclarationNameInfo(D->getDirectiveName());
|
2014-07-21 09:42:05 +00:00
|
|
|
Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-07 13:01:15 +00:00
|
|
|
void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
|
2014-08-19 11:27:13 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-07-07 13:01:15 +00:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-23 09:33:00 +00:00
|
|
|
void ASTStmtWriter::VisitOMPParallelForSimdDirective(
|
|
|
|
OMPParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-12-05 13:43:48 -05:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterDirective(
|
|
|
|
OMPParallelMasterDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE;
|
2022-06-16 16:32:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMaskedDirective(
|
|
|
|
OMPParallelMaskedDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASKED_DIRECTIVE;
|
2019-12-05 13:43:48 -05:00
|
|
|
}
|
|
|
|
|
2014-07-08 08:12:03 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-07-08 08:12:03 +00:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 11:25:16 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2014-07-11 11:25:16 +00:00
|
|
|
Code = serialization::STMT_OMP_TASK_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 10:10:35 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->isXLHSInRHSPart());
|
|
|
|
Record.writeBool(D->isPostfixUpdate());
|
2022-06-02 21:38:12 -04:00
|
|
|
Record.writeBool(D->isFailOnly());
|
2014-07-22 10:10:35 +00:00
|
|
|
Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-19 08:19:49 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-21 13:44:28 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
|
2016-01-19 19:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
|
|
|
|
OMPTargetEnterDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
|
2016-01-19 20:04:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPTargetExitDataDirective(
|
|
|
|
OMPTargetExitDataDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
|
2015-07-21 13:44:28 +00:00
|
|
|
}
|
|
|
|
|
2016-01-26 18:48:41 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelDirective(
|
|
|
|
OMPTargetParallelDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
2020-04-27 11:37:35 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-01-26 18:48:41 +00:00
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-02-03 15:46:42 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-02-03 15:46:42 +00:00
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 07:47:19 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 09:11:51 +00:00
|
|
|
void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 10:17:07 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|
|
|
VisitStmt(D);
|
2021-11-19 05:59:40 -08:00
|
|
|
Record.push_back(D->getNumClauses());
|
2014-07-18 10:17:07 +00:00
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-11-01 14:46:12 -07:00
|
|
|
void ASTStmtWriter::VisitOMPErrorDirective(OMPErrorDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_ERROR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:14:09 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 11:26:11 +00:00
|
|
|
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2020-02-28 09:52:15 -05:00
|
|
|
void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2020-03-20 07:03:01 -04:00
|
|
|
void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SCAN_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 06:45:04 +00:00
|
|
|
void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-10-09 04:18:56 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-01 06:57:41 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeEnum(D->getCancelRegion());
|
2015-07-01 06:57:41 +00:00
|
|
|
Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-07-02 11:25:17 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeEnum(D->getCancelRegion());
|
2015-07-02 11:25:17 +00:00
|
|
|
Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-01 04:18:41 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2015-12-01 04:18:41 +00:00
|
|
|
Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-03 09:40:15 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-10 20:13:02 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2019-10-10 20:13:02 +00:00
|
|
|
Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-06-24 08:42:21 -07:00
|
|
|
void ASTStmtWriter::VisitOMPMaskedTaskLoopDirective(
|
|
|
|
OMPMaskedTaskLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Record.writeBool(D->hasCancel());
|
|
|
|
Code = serialization::STMT_OMP_MASKED_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-18 16:47:35 +00:00
|
|
|
void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective(
|
|
|
|
OMPMasterTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-06-28 14:35:43 -07:00
|
|
|
void ASTStmtWriter::VisitOMPMaskedTaskLoopSimdDirective(
|
|
|
|
OMPMaskedTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASKED_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-14 17:17:41 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2019-10-14 17:17:41 +00:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-06-30 10:59:33 -07:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopDirective(
|
|
|
|
OMPParallelMaskedTaskLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Record.writeBool(D->hasCancel());
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2019-10-25 10:27:13 -04:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterTaskLoopSimdDirective(
|
|
|
|
OMPParallelMasterTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-06-30 17:08:17 -07:00
|
|
|
void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopSimdDirective(
|
|
|
|
OMPParallelMaskedTaskLoopSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-12-14 14:51:25 +00:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-05-26 17:30:50 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-06-27 14:55:37 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-06-27 14:55:37 +00:00
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-05 05:00:15 +00:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
|
|
|
|
OMPDistributeParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-06 04:45:38 +00:00
|
|
|
void ASTStmtWriter::VisitOMPDistributeSimdDirective(
|
|
|
|
OMPDistributeSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-14 02:54:56 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
|
|
|
|
OMPTargetParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-07-20 22:57:10 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-08-05 14:37:37 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
|
|
|
|
OMPTeamsDistributeDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-10-25 12:50:55 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
|
|
|
|
OMPTeamsDistributeSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-11-30 23:51:03 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
|
|
|
|
OMPTeamsDistributeParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-09 03:24:30 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-12-09 03:24:30 +00:00
|
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-17 05:48:59 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-25 04:52:54 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
|
|
|
|
OMPTargetTeamsDistributeDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2016-12-29 22:16:30 +00: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-26 17:42:31 -04:00
|
|
|
Record.writeBool(D->hasCancel());
|
2016-12-29 22:16:30 +00:00
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2017-01-03 05:23:48 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
|
|
|
|
OMPTargetTeamsDistributeParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::
|
|
|
|
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2017-01-10 18:08:18 +00:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
|
|
|
|
OMPTargetTeamsDistributeSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-03-15 13:09:46 -07:00
|
|
|
void ASTStmtWriter::VisitOMPInteropDirective(OMPInteropDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_INTEROP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-03-22 18:13:29 -07:00
|
|
|
void ASTStmtWriter::VisitOMPDispatchDirective(OMPDispatchDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Record.AddSourceLocation(D->getTargetCallLoc());
|
|
|
|
Code = serialization::STMT_OMP_DISPATCH_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-04-09 14:00:36 -05:00
|
|
|
void ASTStmtWriter::VisitOMPMaskedDirective(OMPMaskedDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASKED_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2021-10-28 08:10:40 -07:00
|
|
|
void ASTStmtWriter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_GENERIC_LOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-03-15 08:35:59 -07:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsGenericLoopDirective(
|
|
|
|
OMPTeamsGenericLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-03-18 11:02:02 -07:00
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsGenericLoopDirective(
|
|
|
|
OMPTargetTeamsGenericLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-03-22 10:55:21 -07:00
|
|
|
void ASTStmtWriter::VisitOMPParallelGenericLoopDirective(
|
|
|
|
OMPParallelGenericLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2022-03-23 15:37:06 -07:00
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelGenericLoopDirective(
|
|
|
|
OMPTargetParallelGenericLoopDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
[OpenACC] Implement AST for OpenACC Compute Constructs (#81188)
'serial', 'parallel', and 'kernel' constructs are all considered
'Compute' constructs. This patch creates the AST type, plus the required
infrastructure for such a type, plus some base types that will be useful
in the future for breaking this up.
The only difference between the three is the 'kind'( plus some minor
clause legalization rules, but those can be differentiated easily
enough), so rather than representing them as separate AST nodes, it
seems
to make sense to make them the same.
Additionally, no clause AST functionality is being implemented yet, as
that fits better in a separate patch, and this is enough to get the
'naked' constructs implemented.
This is otherwise an 'NFC' patch, as it doesn't alter execution at all,
so there aren't any tests. I did this to break up the review workload
and to get feedback on the layout.
2024-02-13 06:02:13 -08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenACC Constructs/Directives.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitOpenACCConstructStmt(OpenACCConstructStmt *S) {
|
|
|
|
Record.writeEnum(S->Kind);
|
|
|
|
Record.AddSourceRange(S->Range);
|
|
|
|
// TODO OpenACC: Serialize Clauses.
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOpenACCAssociatedStmtConstruct(
|
|
|
|
OpenACCAssociatedStmtConstruct *S) {
|
|
|
|
VisitOpenACCConstructStmt(S);
|
|
|
|
Record.AddStmt(S->getAssociatedStmt());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
|
|
|
|
VisitStmt(S);
|
2024-03-06 12:28:58 -08:00
|
|
|
VisitOpenACCAssociatedStmtConstruct(S);
|
[OpenACC] Implement AST for OpenACC Compute Constructs (#81188)
'serial', 'parallel', and 'kernel' constructs are all considered
'Compute' constructs. This patch creates the AST type, plus the required
infrastructure for such a type, plus some base types that will be useful
in the future for breaking this up.
The only difference between the three is the 'kind'( plus some minor
clause legalization rules, but those can be differentiated easily
enough), so rather than representing them as separate AST nodes, it
seems
to make sense to make them the same.
Additionally, no clause AST functionality is being implemented yet, as
that fits better in a separate patch, and this is enough to get the
'naked' constructs implemented.
This is otherwise an 'NFC' patch, as it doesn't alter execution at all,
so there aren't any tests. I did this to break up the review workload
and to get feedback on the layout.
2024-02-13 06:02:13 -08:00
|
|
|
Code = serialization::STMT_OPENACC_COMPUTE_CONSTRUCT;
|
|
|
|
}
|
|
|
|
|
2009-04-27 06:20:01 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-08-18 23:56:21 +00:00
|
|
|
// ASTWriter Implementation
|
2009-04-27 06:20:01 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-18 23:56:21 +00:00
|
|
|
unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
|
2023-03-15 18:06:34 -07:00
|
|
|
assert(!SwitchCaseIDs.contains(S) && "SwitchCase recorded twice");
|
2009-04-27 06:20:01 +00:00
|
|
|
unsigned NextID = SwitchCaseIDs.size();
|
|
|
|
SwitchCaseIDs[S] = NextID;
|
|
|
|
return NextID;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:56:21 +00:00
|
|
|
unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
|
2023-03-15 18:06:34 -07:00
|
|
|
assert(SwitchCaseIDs.contains(S) && "SwitchCase hasn't been seen yet");
|
2009-04-27 06:20:01 +00:00
|
|
|
return SwitchCaseIDs[S];
|
|
|
|
}
|
|
|
|
|
2010-10-28 09:29:32 +00:00
|
|
|
void ASTWriter::ClearSwitchCaseIDs() {
|
|
|
|
SwitchCaseIDs.clear();
|
|
|
|
}
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Write the given substatement or subexpression to the
|
2009-04-27 06:20:01 +00:00
|
|
|
/// bitstream.
|
2016-04-06 20:12:34 +00:00
|
|
|
void ASTWriter::WriteSubStmt(Stmt *S) {
|
2009-04-27 06:20:01 +00:00
|
|
|
RecordData Record;
|
2010-08-18 23:56:27 +00:00
|
|
|
ASTStmtWriter Writer(*this, Record);
|
2009-04-27 06:20:01 +00:00
|
|
|
++NumStatements;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2009-04-27 06:20:01 +00:00
|
|
|
if (!S) {
|
2010-08-18 23:57:32 +00:00
|
|
|
Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
|
2009-04-27 06:20:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2011-10-21 23:02:28 +00: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 06:20:01 +00:00
|
|
|
Writer.Visit(S);
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2016-04-06 20:57:53 +00:00
|
|
|
uint64_t Offset = Writer.Emit();
|
|
|
|
SubStmtEntries[S] = Offset;
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Flush all of the statements that have been added to the
|
2009-04-27 06:20:01 +00:00
|
|
|
/// queue via AddStmt().
|
2016-04-06 17:06:00 +00:00
|
|
|
void ASTRecordWriter::FlushStmts() {
|
2012-02-29 02:39:13 +00:00
|
|
|
// We expect to be the only consumer of the two temporary statement maps,
|
|
|
|
// assert that they are empty.
|
2016-04-06 17:06:00 +00:00
|
|
|
assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
|
|
|
|
assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
|
2011-10-21 23:02:28 +00:00
|
|
|
|
2009-04-27 06:20:01 +00:00
|
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
2016-04-06 20:12:34 +00:00
|
|
|
Writer->WriteSubStmt(StmtsToEmit[I]);
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2016-04-06 17:06:00 +00:00
|
|
|
assert(N == StmtsToEmit.size() && "record modified while being written!");
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2009-04-27 06:20:01 +00: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-06 17:06:00 +00:00
|
|
|
Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());
|
|
|
|
|
|
|
|
Writer->SubStmtEntries.clear();
|
|
|
|
Writer->ParentStmts.clear();
|
|
|
|
}
|
2011-10-21 23:02:28 +00:00
|
|
|
|
2016-04-06 17:06:00 +00: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-06 20:12:34 +00:00
|
|
|
Writer->WriteSubStmt(StmtsToEmit[N - I - 1]);
|
2016-04-06 17:06:00 +00:00
|
|
|
assert(N == StmtsToEmit.size() && "record modified while being written!");
|
2009-04-27 06:20:01 +00:00
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2009-04-27 06:20:01 +00:00
|
|
|
StmtsToEmit.clear();
|
|
|
|
}
|