100 changes: 73 additions & 27 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1452,8 +1452,6 @@ floating point semantic models: precise (the default), strict, and fast.
"fenv_access", "off", "on", "off"
"rounding_mode", "tonearest", "dynamic", "tonearest"
"contract", "on", "off", "fast"
"denormal_fp_math", "IEEE", "IEEE", "IEEE"
"denormal_fp32_math", "IEEE","IEEE", "IEEE"
"support_math_errno", "on", "on", "off"
"no_honor_nans", "off", "off", "on"
"no_honor_infinities", "off", "off", "on"
Expand All @@ -1462,6 +1460,14 @@ floating point semantic models: precise (the default), strict, and fast.
"allow_approximate_fns", "off", "off", "on"
"allow_reassociation", "off", "off", "on"

The ``-ffp-model`` option does not modify the ``fdenormal-fp-math``
setting, but it does have an impact on whether ``crtfastmath.o`` is
linked. Because linking ``crtfastmath.o`` has a global effect on the
program, and because the global denormal handling can be changed in
other ways, the state of ``fdenormal-fp-math`` handling cannot
be assumed in any function based on fp-model. See :ref:`crtfastmath.o`
for more details.

.. option:: -ffast-math

Enable fast-math mode. This option lets the
Expand Down Expand Up @@ -1506,7 +1512,8 @@ floating point semantic models: precise (the default), strict, and fast.

* ``-ffp-contract=fast``

Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code. See
Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code unless
``-shared`` or ``-mno-daz-ftz`` is present. See
:ref:`crtfastmath.o` for more details.

.. option:: -fno-fast-math
Expand Down Expand Up @@ -1536,7 +1543,6 @@ floating point semantic models: precise (the default), strict, and fast.
Also, this option resets following options to their target-dependent defaults.

* ``-f[no-]math-errno``
* ``-fdenormal-fp-math=<value>``

There is ambiguity about how ``-ffp-contract``, ``-ffast-math``,
and ``-fno-fast-math`` behave when combined. To keep the value of
Expand All @@ -1559,8 +1565,8 @@ floating point semantic models: precise (the default), strict, and fast.
``-ffp-contract`` setting is determined by the default value of
``-ffp-contract``.

Note: ``-fno-fast-math`` implies ``-fdenormal-fp-math=ieee``.
``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code.
Note: ``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code
unless ``-mdaz-ftz`` is present.

.. option:: -fdenormal-fp-math=<value>

Expand Down Expand Up @@ -1690,9 +1696,7 @@ floating point semantic models: precise (the default), strict, and fast.
* ``-fno-associative-math``
* ``-fno-reciprocal-math``
* ``-fsigned-zeros``
* ``-ftrapping-math``
* ``-ffp-contract=on``
* ``-fdenormal-fp-math=ieee``

There is ambiguity about how ``-ffp-contract``,
``-funsafe-math-optimizations``, and ``-fno-unsafe-math-optimizations``
Expand Down Expand Up @@ -1938,10 +1942,13 @@ by using ``#pragma STDC FENV_ROUND`` with a value other than ``FE_DYNAMIC``.

A note about ``crtfastmath.o``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``-ffast-math`` and ``-funsafe-math-optimizations`` cause ``crtfastmath.o`` to be
automatically linked, which adds a static constructor that sets the FTZ/DAZ
``-ffast-math`` and ``-funsafe-math-optimizations`` without the ``-shared``
option cause ``crtfastmath.o`` to be
automatically linked, which adds a static constructor that sets the FTZ/DAZ
bits in MXCSR, affecting not only the current compilation unit but all static
and shared libraries included in the program.
and shared libraries included in the program. This decision can be overridden
by using either the flag ``-mdaz-ftz`` or ``-mno-daz-ftz`` to respectively
link or not link ``crtfastmath.o``.

.. _FLT_EVAL_METHOD:

Expand Down Expand Up @@ -2314,6 +2321,8 @@ are listed below.
on ELF targets when using the integrated assembler. This flag currently
only has an effect on ELF targets.

.. _funique_internal_linkage_names:

.. option:: -f[no]-unique-internal-linkage-names

Controls whether Clang emits a unique (best-effort) symbol name for internal
Expand Down Expand Up @@ -2443,27 +2452,41 @@ usual build cycle when using sample profilers for optimization:
usual build flags that you always build your application with. The only
requirement is that DWARF debug info including source line information is
generated. This DWARF information is important for the profiler to be able
to map instructions back to source line locations.
to map instructions back to source line locations. The usefulness of this
DWARF information can be improved with the ``-fdebug-info-for-profiling``
and ``-funique-internal-linkage-names`` options.

On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
On Linux:

.. code-block:: console
$ clang++ -O2 -gline-tables-only code.cc -o code
$ clang++ -O2 -gline-tables-only \
-fdebug-info-for-profiling -funique-internal-linkage-names \
code.cc -o code
While MSVC-style targets default to CodeView debug information, DWARF debug
information is required to generate source-level LLVM profiles. Use
``-gdwarf`` to include DWARF debug information:

.. code-block:: console
.. code-block:: winbatch
> clang-cl /O2 -gdwarf -gline-tables-only ^
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
$ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld -link -debug:dwarf
.. note::

:ref:`-funique-internal-linkage-names <funique_internal_linkage_names>`
generates unique names based on given command-line source file paths. If
your build system uses absolute source paths and these paths may change
between steps 1 and 4, then the uniqued function names may change and result
in unused profile data. Consider omitting this option in such cases.

2. Run the executable under a sampling profiler. The specific profiler
you use does not really matter, as long as its output can be converted
into the format that the LLVM optimizer understands.

Two such profilers are the the Linux Perf profiler
Two such profilers are the Linux Perf profiler
(https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP),
available as part of `Intel VTune
<https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/vtune-profiler.html>`_.
Expand All @@ -2477,7 +2500,9 @@ usual build cycle when using sample profilers for optimization:

.. code-block:: console
$ perf record -b ./code
$ perf record -b -e BR_INST_RETIRED.NEAR_TAKEN:uppp ./code
If the event above is unavailable, ``branches:u`` is probably next-best.

Note the use of the ``-b`` flag. This tells Perf to use the Last Branch
Record (LBR) to record call chains. While this is not strictly required,
Expand Down Expand Up @@ -2527,21 +2552,42 @@ usual build cycle when using sample profilers for optimization:
that executes faster than the original one. Note that you are not
required to build the code with the exact same arguments that you
used in the first step. The only requirement is that you build the code
with ``-gline-tables-only`` and ``-fprofile-sample-use``.
with the same debug info options and ``-fprofile-sample-use``.

On Linux:

.. code-block:: console
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code
$ clang++ -O2 -gline-tables-only \
-fdebug-info-for-profiling -funique-internal-linkage-names \
-fprofile-sample-use=code.prof code.cc -o code
[OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/
edge counters. The profile inference algorithm (profi) can be used to infer
missing blocks and edge counts, and improve the quality of profile data.
Enable it with ``-fsample-profile-use-profi``.
On Windows:

.. code-block:: console
.. code-block:: winbatch
> clang-cl /O2 -gdwarf -gline-tables-only ^
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
/fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
[OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/
edge counters. The profile inference algorithm (profi) can be used to infer
missing blocks and edge counts, and improve the quality of profile data.
Enable it with ``-fsample-profile-use-profi``. For example, on Linux:

.. code-block:: console
$ clang++ -fsample-profile-use-profi -O2 -gline-tables-only \
-fdebug-info-for-profiling -funique-internal-linkage-names \
-fprofile-sample-use=code.prof code.cc -o code
On Windows:

.. code-block:: winbatch
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof \
-fsample-profile-use-profi code.cc -o code
> clang-cl /clang:-fsample-profile-use-profi /O2 -gdwarf -gline-tables-only ^
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
/fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
Sample Profile Formats
""""""""""""""""""""""
Expand Down
186 changes: 93 additions & 93 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,99 @@ checker).
Default value of the option is ``true``.
.. _unix-Stream:
unix.Stream (C)
"""""""""""""""
Check C stream handling functions:
``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.
The checker maintains information about the C stream objects (``FILE *``) and
can detect error conditions related to use of streams. The following conditions
are detected:
* The ``FILE *`` pointer passed to the function is NULL (the single exception is
``fflush`` where NULL is allowed).
* Use of stream after close.
* Opened stream is not closed.
* Read from a stream after end-of-file. (This is not a fatal error but reported
by the checker. Stream remains in EOF state and the read operation fails.)
* Use of stream when the file position is indeterminate after a previous failed
operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
void test1() {
FILE *p = fopen("foo", "r");
} // warn: opened file is never closed
void test2() {
FILE *p = fopen("foo", "r");
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
fclose(p);
}
void test3() {
FILE *p = fopen("foo", "r");
if (p) {
fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
fclose(p);
}
}
void test4() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fclose(p);
fclose(p); // warn: stream already closed
}
void test5() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!ferror(p))
fgetc(p); // warn: possible read after end-of-file
fclose(p);
}
void test6() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!feof(p))
fgetc(p); // warn: file position may be indeterminate after I/O error
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _osx-checkers:
osx
Expand Down Expand Up @@ -3116,99 +3209,6 @@ Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fcl
fclose(F); // warn: closing a previously closed file stream
}
.. _alpha-unix-Stream:
alpha.unix.Stream (C)
"""""""""""""""""""""
Check C stream handling functions:
``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.
The checker maintains information about the C stream objects (``FILE *``) and
can detect error conditions related to use of streams. The following conditions
are detected:
* The ``FILE *`` pointer passed to the function is NULL (the single exception is
``fflush`` where NULL is allowed).
* Use of stream after close.
* Opened stream is not closed.
* Read from a stream after end-of-file. (This is not a fatal error but reported
by the checker. Stream remains in EOF state and the read operation fails.)
* Use of stream when the file position is indeterminate after a previous failed
operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config alpha.unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
void test1() {
FILE *p = fopen("foo", "r");
} // warn: opened file is never closed
void test2() {
FILE *p = fopen("foo", "r");
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
fclose(p);
}
void test3() {
FILE *p = fopen("foo", "r");
if (p) {
fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
fclose(p);
}
}
void test4() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fclose(p);
fclose(p); // warn: stream already closed
}
void test5() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!ferror(p))
fgetc(p); // warn: possible read after end-of-file
fclose(p);
}
void test6() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!feof(p))
fgetc(p); // warn: file position may be indeterminate after I/O error
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _alpha-unix-cstring-BufferOverlap:
alpha.unix.cstring.BufferOverlap (C)
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -1644,8 +1644,9 @@ enum CXCursorKind {
CXCursor_ObjCSelfExpr = 146,

/** OpenMP 5.0 [2.1.5, Array Section].
* OpenACC 3.3 [2.7.1, Data Specification for Data Clauses (Sub Arrays)]
*/
CXCursor_OMPArraySectionExpr = 147,
CXCursor_ArraySectionExpr = 147,

/** Represents an @available(...) check.
*/
Expand Down
22 changes: 21 additions & 1 deletion clang/include/clang/APINotes/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,14 +675,21 @@ class TagInfo : public CommonTypeInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned IsFlagEnum : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned SwiftCopyableSpecified : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftCopyable : 1;

public:
std::optional<std::string> SwiftImportAs;
std::optional<std::string> SwiftRetainOp;
std::optional<std::string> SwiftReleaseOp;

std::optional<EnumExtensibilityKind> EnumExtensibility;

TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
TagInfo()
: HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false),
SwiftCopyable(false) {}

std::optional<bool> isFlagEnum() const {
if (HasFlagEnum)
Expand All @@ -694,6 +701,15 @@ class TagInfo : public CommonTypeInfo {
IsFlagEnum = Value.value_or(false);
}

std::optional<bool> isSwiftCopyable() const {
return SwiftCopyableSpecified ? std::optional<bool>(SwiftCopyable)
: std::nullopt;
}
void setSwiftCopyable(std::optional<bool> Value) {
SwiftCopyableSpecified = Value.has_value();
SwiftCopyable = Value.value_or(false);
}

TagInfo &operator|=(const TagInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;

Expand All @@ -710,6 +726,9 @@ class TagInfo : public CommonTypeInfo {
if (!EnumExtensibility)
EnumExtensibility = RHS.EnumExtensibility;

if (!SwiftCopyableSpecified)
setSwiftCopyable(RHS.isSwiftCopyable());

return *this;
}

Expand All @@ -724,6 +743,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
LHS.isFlagEnum() == RHS.isFlagEnum() &&
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
LHS.EnumExtensibility == RHS.EnumExtensibility;
}

Expand Down
17 changes: 14 additions & 3 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// initialization of another module).
struct PerModuleInitializers {
llvm::SmallVector<Decl*, 4> Initializers;
llvm::SmallVector<Decl::DeclID, 4> LazyInitializers;
llvm::SmallVector<GlobalDeclID, 4> LazyInitializers;

void resolve(ASTContext &Ctx);
};
Expand Down Expand Up @@ -1059,7 +1059,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// or an ImportDecl nominating another module that has initializers.
void addModuleInitializer(Module *M, Decl *Init);

void addLazyModuleInitializers(Module *M, ArrayRef<Decl::DeclID> IDs);
void addLazyModuleInitializers(Module *M, ArrayRef<GlobalDeclID> IDs);

/// Get the initializations to perform when importing a module, if any.
ArrayRef<Decl*> getModuleInitializers(Module *M);
Expand Down Expand Up @@ -1127,7 +1127,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
CanQualType OCLQueueTy, OCLReserveIDTy;
CanQualType IncompleteMatrixIdxTy;
CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy;
CanQualType ArraySectionTy;
CanQualType OMPArrayShapingTy, OMPIteratorTy;
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
CanQualType Id##Ty;
#include "clang/Basic/OpenCLExtensionTypes.def"
Expand Down Expand Up @@ -2196,6 +2197,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getQualifiedType(type.getUnqualifiedType(), Qs);
}

/// \brief Return a type with the given __ptrauth qualifier.
QualType getPointerAuthType(QualType Ty, PointerAuthQualifier PointerAuth) {
assert(!Ty.getPointerAuth());
assert(PointerAuth);

Qualifiers Qs;
Qs.setPointerAuth(PointerAuth);
return getQualifiedType(Ty, Qs);
}

unsigned char getFixedPointScale(QualType Ty) const;
unsigned char getFixedPointIBits(QualType Ty) const;
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,12 @@ class ASTNodeTraverser
}
}

void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) {
if (E->hasExplicitTemplateArgs())
for (auto Arg : E->template_arguments())
Visit(Arg.getArgument());
}

void VisitRequiresExpr(const RequiresExpr *E) {
for (auto *D : E->getLocalParameters())
Visit(D);
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/AST/AbstractBasicReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
}

Qualifiers readQualifiers() {
static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t),
static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint64_t),
"update this if the value size changes");
uint32_t value = asImpl().readUInt32();
uint64_t value = asImpl().readUInt64();
return Qualifiers::fromOpaqueValue(value);
}

Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/AST/AbstractBasicWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
}

void writeQualifiers(Qualifiers value) {
static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint64_t),
"update this if the value size changes");
asImpl().writeUInt32(value.getAsOpaqueValue());
asImpl().writeUInt64(value.getAsOpaqueValue());
}

void writeExceptionSpecInfo(
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/BuiltinTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy)

// A placeholder type for OpenMP array sections.
PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
PLACEHOLDER_TYPE(ArraySection, ArraySectionTy)

// A placeholder type for OpenMP array shaping operation.
PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy)
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/AST/ComputeDependence.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class DesignatedInitExpr;
class ParenListExpr;
class PseudoObjectExpr;
class AtomicExpr;
class OMPArraySectionExpr;
class ArraySectionExpr;
class OMPArrayShapingExpr;
class OMPIteratorExpr;
class ObjCArrayLiteral;
Expand Down Expand Up @@ -189,7 +189,7 @@ ExprDependence computeDependence(ParenListExpr *E);
ExprDependence computeDependence(PseudoObjectExpr *E);
ExprDependence computeDependence(AtomicExpr *E);

ExprDependence computeDependence(OMPArraySectionExpr *E);
ExprDependence computeDependence(ArraySectionExpr *E);
ExprDependence computeDependence(OMPArrayShapingExpr *E);
ExprDependence computeDependence(OMPIteratorExpr *E);

Expand Down
46 changes: 23 additions & 23 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class PragmaCommentDecl final
SourceLocation CommentLoc,
PragmaMSCommentKind CommentKind,
StringRef Arg);
static PragmaCommentDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned ArgSize);

PragmaMSCommentKind getCommentKind() const { return CommentKind; }
Expand Down Expand Up @@ -192,7 +192,7 @@ class PragmaDetectMismatchDecl final
SourceLocation Loc, StringRef Name,
StringRef Value);
static PragmaDetectMismatchDecl *
CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize);
CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize);

StringRef getName() const { return getTrailingObjects<char>(); }
StringRef getValue() const { return getTrailingObjects<char>() + ValueStart; }
Expand Down Expand Up @@ -518,7 +518,7 @@ class LabelDecl : public NamedDecl {
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II,
SourceLocation GnuLabelL);
static LabelDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

LabelStmt *getStmt() const { return TheStmt; }
void setStmt(LabelStmt *T) { TheStmt = T; }
Expand Down Expand Up @@ -581,7 +581,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext,
IdentifierInfo *Id, NamespaceDecl *PrevDecl,
bool Nested);

static NamespaceDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

using redecl_range = redeclarable_base::redecl_range;
using redecl_iterator = redeclarable_base::redecl_iterator;
Expand Down Expand Up @@ -1146,7 +1146,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass S);

static VarDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -1728,7 +1728,7 @@ class ImplicitParamDecl : public VarDecl {
static ImplicitParamDecl *Create(ASTContext &C, QualType T,
ImplicitParamKind ParamKind);

static ImplicitParamDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
const IdentifierInfo *Id, QualType Type,
Expand Down Expand Up @@ -1782,7 +1782,7 @@ class ParmVarDecl : public VarDecl {
TypeSourceInfo *TInfo, StorageClass S,
Expr *DefArg);

static ParmVarDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -2178,7 +2178,7 @@ class FunctionDecl : public DeclaratorDecl,
bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause);

static FunctionDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
Expand Down Expand Up @@ -3136,7 +3136,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle);

static FieldDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Returns the index of this field within its record,
/// as appropriate for passing to ASTRecordLayout::getFieldOffset.
Expand Down Expand Up @@ -3311,7 +3311,7 @@ class EnumConstantDecl : public ValueDecl,
SourceLocation L, IdentifierInfo *Id,
QualType T, Expr *E,
const llvm::APSInt &V);
static EnumConstantDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

const Expr *getInitExpr() const { return (const Expr*) Init; }
Expr *getInitExpr() { return (Expr*) Init; }
Expand Down Expand Up @@ -3357,7 +3357,7 @@ class IndirectFieldDecl : public ValueDecl,
QualType T,
llvm::MutableArrayRef<NamedDecl *> CH);

static IndirectFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

using chain_iterator = ArrayRef<NamedDecl *>::const_iterator;

Expand Down Expand Up @@ -3542,7 +3542,7 @@ class TypedefDecl : public TypedefNameDecl {
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
const IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypedefDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand All @@ -3567,7 +3567,7 @@ class TypeAliasDecl : public TypedefNameDecl {
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
const IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypeAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -3977,7 +3977,7 @@ class EnumDecl : public TagDecl {
IdentifierInfo *Id, EnumDecl *PrevDecl,
bool IsScoped, bool IsScopedUsingClassTag,
bool IsFixed);
static EnumDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Overrides to provide correct range when there's an enum-base specifier
/// with forward declarations.
Expand Down Expand Up @@ -4182,7 +4182,7 @@ class RecordDecl : public TagDecl {
static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
static RecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID);
static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID);

RecordDecl *getPreviousDecl() {
return cast_or_null<RecordDecl>(
Expand Down Expand Up @@ -4433,7 +4433,7 @@ class FileScopeAsmDecl : public Decl {
StringLiteral *Str, SourceLocation AsmLoc,
SourceLocation RParenLoc);

static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceLocation getAsmLoc() const { return getLocation(); }
SourceLocation getRParenLoc() const { return RParenLoc; }
Expand Down Expand Up @@ -4469,7 +4469,7 @@ class TopLevelStmtDecl : public Decl, public DeclContext {

public:
static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement);
static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;
Stmt *getStmt() { return Statement; }
Expand Down Expand Up @@ -4563,7 +4563,7 @@ class BlockDecl : public Decl, public DeclContext {

public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
static BlockDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceLocation getCaretLocation() const { return getLocation(); }

Expand Down Expand Up @@ -4717,7 +4717,7 @@ class CapturedDecl final

static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
unsigned NumParams);
static CapturedDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned NumParams);

Stmt *getBody() const override;
Expand Down Expand Up @@ -4851,7 +4851,7 @@ class ImportDecl final : public Decl,
SourceLocation EndLoc);

/// Create a new, deserialized module import declaration.
static ImportDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned NumLocations);

/// Retrieve the module that was imported by the import declaration.
Expand Down Expand Up @@ -4892,7 +4892,7 @@ class ExportDecl final : public Decl, public DeclContext {
public:
static ExportDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation ExportLoc);
static ExportDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceLocation getExportLoc() const { return getLocation(); }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
Expand Down Expand Up @@ -4931,7 +4931,7 @@ class EmptyDecl : public Decl {
public:
static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L);
static EmptyDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Empty; }
Expand All @@ -4957,7 +4957,7 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext {
bool CBuffer, SourceLocation KwLoc,
IdentifierInfo *ID, SourceLocation IDLoc,
SourceLocation LBrace);
static HLSLBufferDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocStart(), RBraceLoc);
Expand Down
12 changes: 5 additions & 7 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclID.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/SelectorLocationsKind.h"
#include "clang/Basic/IdentifierTable.h"
Expand Down Expand Up @@ -239,9 +240,6 @@ class alignas(8) Decl {
ModulePrivate
};

/// An ID number that refers to a declaration in an AST file.
using DeclID = uint32_t;

protected:
/// The next declaration within the same lexical
/// DeclContext. These pointers form the linked list that is
Expand Down Expand Up @@ -361,7 +359,7 @@ class alignas(8) Decl {
/// \param Ctx The context in which we will allocate memory.
/// \param ID The global ID of the deserialized declaration.
/// \param Extra The amount of extra space to allocate after the object.
void *operator new(std::size_t Size, const ASTContext &Ctx, DeclID ID,
void *operator new(std::size_t Size, const ASTContext &Ctx, GlobalDeclID ID,
std::size_t Extra = 0);

/// Allocate memory for a non-deserialized declaration.
Expand Down Expand Up @@ -779,10 +777,10 @@ class alignas(8) Decl {

/// Retrieve the global declaration ID associated with this
/// declaration, which specifies where this Decl was loaded from.
DeclID getGlobalID() const {
GlobalDeclID getGlobalID() const {
if (isFromASTFile())
return *((const DeclID *)this - 1);
return 0;
return (*((const GlobalDeclID *)this - 1));
return GlobalDeclID();
}

/// Retrieve the global ID of the module that owns this particular
Expand Down
59 changes: 31 additions & 28 deletions clang/include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class AccessSpecDecl : public Decl {
return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
}

static AccessSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static AccessSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Expand Down Expand Up @@ -579,7 +579,8 @@ class CXXRecordDecl : public RecordDecl {
TypeSourceInfo *Info, SourceLocation Loc,
unsigned DependencyKind, bool IsGeneric,
LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C,
GlobalDeclID ID);

bool isDynamicClass() const {
return data().Polymorphic || data().NumVBases != 0;
Expand Down Expand Up @@ -1980,7 +1981,8 @@ class CXXDeductionGuideDecl : public FunctionDecl {
CXXConstructorDecl *Ctor = nullptr,
DeductionCandidate Kind = DeductionCandidate::Normal);

static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; }
const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; }
Expand Down Expand Up @@ -2035,7 +2037,8 @@ class RequiresExprBodyDecl : public Decl, public DeclContext {
static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc);

static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Expand Down Expand Up @@ -2078,7 +2081,7 @@ class CXXMethodDecl : public FunctionDecl {
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr);

static CXXMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

bool isStatic() const;
bool isInstance() const { return !isStatic(); }
Expand Down Expand Up @@ -2579,7 +2582,7 @@ class CXXConstructorDecl final
friend class ASTDeclWriter;
friend TrailingObjects;

static CXXConstructorDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
uint64_t AllocKind);
static CXXConstructorDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
Expand Down Expand Up @@ -2822,7 +2825,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, DeclID ID);
static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);

Expand Down Expand Up @@ -2881,7 +2884,7 @@ class CXXConversionDecl : public CXXMethodDecl {
bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

ExplicitSpecifier getExplicitSpecifier() {
return getCanonicalDecl()->ExplicitSpec;
Expand Down Expand Up @@ -2948,7 +2951,7 @@ class LinkageSpecDecl : public Decl, public DeclContext {
SourceLocation ExternLoc,
SourceLocation LangLoc,
LinkageSpecLanguageIDs Lang, bool HasBraces);
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Return the language specified by this linkage specification.
LinkageSpecLanguageIDs getLanguage() const {
Expand Down Expand Up @@ -3096,7 +3099,7 @@ class UsingDirectiveDecl : public NamedDecl {
SourceLocation IdentLoc,
NamedDecl *Nominated,
DeclContext *CommonAncestor);
static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(UsingLoc, getLocation());
Expand Down Expand Up @@ -3157,7 +3160,7 @@ class NamespaceAliasDecl : public NamedDecl,
SourceLocation IdentLoc,
NamedDecl *Namespace);

static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

using redecl_range = redeclarable_base::redecl_range;
using redecl_iterator = redeclarable_base::redecl_iterator;
Expand Down Expand Up @@ -3254,7 +3257,7 @@ class LifetimeExtendedTemporaryDecl final
LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling);
}
static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C,
DeclID ID) {
GlobalDeclID ID) {
return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{});
}

Expand Down Expand Up @@ -3357,7 +3360,7 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target);
}

static UsingShadowDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static UsingShadowDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

using redecl_range = redeclarable_base::redecl_range;
using redecl_iterator = redeclarable_base::redecl_iterator;
Expand Down Expand Up @@ -3566,7 +3569,7 @@ class UsingDecl : public BaseUsingDecl, public Mergeable<UsingDecl> {
const DeclarationNameInfo &NameInfo,
bool HasTypenameKeyword);

static UsingDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static UsingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -3645,7 +3648,7 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
UsingDecl *Using, NamedDecl *Target,
bool IsVirtual);
static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
GlobalDeclID ID);

/// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that
/// introduced this.
Expand Down Expand Up @@ -3757,7 +3760,7 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
SourceLocation UsingL, SourceLocation EnumL,
SourceLocation NameL, TypeSourceInfo *EnumType);

static UsingEnumDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static UsingEnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -3830,7 +3833,7 @@ class UsingPackDecl final
NamedDecl *InstantiatedFrom,
ArrayRef<NamedDecl *> UsingDecls);

static UsingPackDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static UsingPackDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned NumExpansions);

SourceRange getSourceRange() const override LLVM_READONLY {
Expand Down Expand Up @@ -3923,8 +3926,8 @@ class UnresolvedUsingValueDecl : public ValueDecl,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc);

static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, DeclID ID);
static UnresolvedUsingValueDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -4014,8 +4017,8 @@ class UnresolvedUsingTypenameDecl
SourceLocation TargetNameLoc, DeclarationName TargetName,
SourceLocation EllipsisLoc);

static UnresolvedUsingTypenameDecl *
CreateDeserialized(ASTContext &C, DeclID ID);
static UnresolvedUsingTypenameDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

/// Retrieves the canonical declaration of this declaration.
UnresolvedUsingTypenameDecl *getCanonicalDecl() override {
Expand Down Expand Up @@ -4045,7 +4048,7 @@ class UnresolvedUsingIfExistsDecl final : public NamedDecl {
SourceLocation Loc,
DeclarationName Name);
static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx,
DeclID ID);
GlobalDeclID ID);

static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; }
Expand Down Expand Up @@ -4073,7 +4076,7 @@ class StaticAssertDecl : public Decl {
SourceLocation StaticAssertLoc,
Expr *AssertExpr, Expr *Message,
SourceLocation RParenLoc, bool Failed);
static StaticAssertDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static StaticAssertDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
Expand Down Expand Up @@ -4120,7 +4123,7 @@ class BindingDecl : public ValueDecl {

static BindingDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id);
static BindingDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Get the expression to which this declaration is bound. This may be null
/// in two different cases: while parsing the initializer for the
Expand Down Expand Up @@ -4189,7 +4192,7 @@ class DecompositionDecl final
QualType T, TypeSourceInfo *TInfo,
StorageClass S,
ArrayRef<BindingDecl *> Bindings);
static DecompositionDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned NumBindings);

ArrayRef<BindingDecl *> bindings() const {
Expand Down Expand Up @@ -4246,7 +4249,7 @@ class MSPropertyDecl : public DeclaratorDecl {
SourceLocation L, DeclarationName N, QualType T,
TypeSourceInfo *TInfo, SourceLocation StartL,
IdentifierInfo *Getter, IdentifierInfo *Setter);
static MSPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static MSPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

static bool classof(const Decl *D) { return D->getKind() == MSProperty; }

Expand Down Expand Up @@ -4300,7 +4303,7 @@ class MSGuidDecl : public ValueDecl,
MSGuidDecl(DeclContext *DC, QualType T, Parts P);

static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P);
static MSGuidDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static MSGuidDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

// Only ASTContext::getMSGuidDecl and deserialization create these.
friend class ASTContext;
Expand Down Expand Up @@ -4353,7 +4356,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl,
static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T,
const APValue &APVal);
static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
GlobalDeclID ID);

// Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create
// these.
Expand Down
39 changes: 23 additions & 16 deletions clang/include/clang/AST/DeclContextInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ class StoredDeclsList {
/// external declarations.
DeclsAndHasExternalTy Data;

template<typename Fn>
void erase_if(Fn ShouldErase) {
template <typename Fn> DeclListNode::Decls *erase_if(Fn ShouldErase) {
Decls List = Data.getPointer();

if (!List)
return;
return nullptr;

ASTContext &C = getASTContext();
DeclListNode::Decls NewHead = nullptr;
DeclListNode::Decls *NewLast = nullptr;
Expand Down Expand Up @@ -79,6 +80,17 @@ class StoredDeclsList {
Data.setPointer(NewHead);

assert(llvm::none_of(getLookupResult(), ShouldErase) && "Still exists!");

if (!Data.getPointer())
// All declarations are erased.
return nullptr;
else if (NewHead.is<NamedDecl *>())
// The list only contains a declaration, the header itself.
return (DeclListNode::Decls *)&Data;
else {
assert(NewLast && NewLast->is<NamedDecl *>() && "Not the tail?");
return NewLast;
}
}

void erase(NamedDecl *ND) {
Expand Down Expand Up @@ -160,12 +172,16 @@ class StoredDeclsList {

void replaceExternalDecls(ArrayRef<NamedDecl*> Decls) {
// Remove all declarations that are either external or are replaced with
// external declarations.
erase_if([Decls](NamedDecl *ND) {
// external declarations with higher visibilities.
DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) {
if (ND->isFromASTFile())
return true;
// FIXME: Can we get rid of this loop completely?
for (NamedDecl *D : Decls)
if (D->declarationReplaces(ND, /*IsKnownNewer=*/false))
// Only replace the local declaration if the external declaration has
// higher visibilities.
if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() &&
D->declarationReplaces(ND, /*IsKnownNewer=*/false))
return true;
return false;
});
Expand All @@ -185,24 +201,15 @@ class StoredDeclsList {
DeclsAsList = Node;
}

DeclListNode::Decls Head = Data.getPointer();
if (Head.isNull()) {
if (!Data.getPointer()) {
Data.setPointer(DeclsAsList);
return;
}

// Find the end of the existing list.
// FIXME: It would be possible to preserve information from erase_if to
// avoid this rescan looking for the end of the list.
DeclListNode::Decls *Tail = &Head;
while (DeclListNode *Node = Tail->dyn_cast<DeclListNode *>())
Tail = &Node->Rest;

// Append the Decls.
DeclListNode *Node = C.AllocateDeclListNode(Tail->get<NamedDecl *>());
Node->Rest = DeclsAsList;
*Tail = Node;
Data.setPointer(Head);
}

/// Return the list of all the decls.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/DeclFriend.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class FriendDecl final
Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
SourceLocation FriendL,
ArrayRef<TemplateParameterList *> FriendTypeTPLists = std::nullopt);
static FriendDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned FriendTypeNumTPLists);

/// If this friend declaration names an (untemplated but possibly
Expand Down
227 changes: 227 additions & 0 deletions clang/include/clang/AST/DeclID.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
//===--- DeclID.h - ID number for deserialized declarations ----*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines DeclID class family to describe the deserialized
// declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to
// `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to
// require the use of `DeclID` to explicit.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_DECLID_H
#define LLVM_CLANG_AST_DECLID_H

#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/iterator.h"

namespace clang {

/// Predefined declaration IDs.
///
/// These declaration IDs correspond to predefined declarations in the AST
/// context, such as the NULL declaration ID. Such declarations are never
/// actually serialized, since they will be built by the AST context when
/// it is created.
enum PredefinedDeclIDs {
/// The NULL declaration.
PREDEF_DECL_NULL_ID = 0,

/// The translation unit.
PREDEF_DECL_TRANSLATION_UNIT_ID = 1,

/// The Objective-C 'id' type.
PREDEF_DECL_OBJC_ID_ID = 2,

/// The Objective-C 'SEL' type.
PREDEF_DECL_OBJC_SEL_ID = 3,

/// The Objective-C 'Class' type.
PREDEF_DECL_OBJC_CLASS_ID = 4,

/// The Objective-C 'Protocol' type.
PREDEF_DECL_OBJC_PROTOCOL_ID = 5,

/// The signed 128-bit integer type.
PREDEF_DECL_INT_128_ID = 6,

/// The unsigned 128-bit integer type.
PREDEF_DECL_UNSIGNED_INT_128_ID = 7,

/// The internal 'instancetype' typedef.
PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,

/// The internal '__builtin_va_list' typedef.
PREDEF_DECL_BUILTIN_VA_LIST_ID = 9,

/// The internal '__va_list_tag' struct, if any.
PREDEF_DECL_VA_LIST_TAG = 10,

/// The internal '__builtin_ms_va_list' typedef.
PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11,

/// The predeclared '_GUID' struct.
PREDEF_DECL_BUILTIN_MS_GUID_ID = 12,

/// The extern "C" context.
PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13,

/// The internal '__make_integer_seq' template.
PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14,

/// The internal '__NSConstantString' typedef.
PREDEF_DECL_CF_CONSTANT_STRING_ID = 15,

/// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16,

/// The internal '__type_pack_element' template.
PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17,
};

/// The number of declaration IDs that are predefined.
///
/// For more information about predefined declarations, see the
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
const unsigned int NUM_PREDEF_DECL_IDS = 18;

/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means
/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the
/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID.
/// Outside the serializer, all the DeclID been used should be GlobalDeclID.
/// We can translate a LocalDeclID to the GlobalDeclID by
/// `ASTReader::getGlobalDeclID()`.

class DeclIDBase {
public:
/// An ID number that refers to a declaration in an AST file.
///
/// The ID numbers of declarations are consecutive (in order of
/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved.
/// At the start of a chain of precompiled headers, declaration ID 1 is
/// used for the translation unit declaration.
///
/// DeclID should only be used directly in serialization. All other users
/// should use LocalDeclID or GlobalDeclID.
using DeclID = uint32_t;

protected:
DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
explicit DeclIDBase(DeclID ID) : ID(ID) {}

public:
DeclID get() const { return ID; }

explicit operator DeclID() const { return ID; }

explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; }

bool isValid() const { return ID != PREDEF_DECL_NULL_ID; }

bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; }

friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID == RHS.ID;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID != RHS.ID;
}
// We may sort the decl ID.
friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID < RHS.ID;
}
friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID > RHS.ID;
}
friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID <= RHS.ID;
}
friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID >= RHS.ID;
}

protected:
DeclID ID;
};

class LocalDeclID : public DeclIDBase {
using Base = DeclIDBase;

public:
LocalDeclID() : Base() {}
LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
explicit LocalDeclID(DeclID ID) : Base(ID) {}

LocalDeclID &operator++() {
++ID;
return *this;
}

LocalDeclID operator++(int) {
LocalDeclID Ret = *this;
++(*this);
return Ret;
}
};

class GlobalDeclID : public DeclIDBase {
using Base = DeclIDBase;

public:
GlobalDeclID() : Base() {}
explicit GlobalDeclID(DeclID ID) : Base(ID) {}

// For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID
// to a LocalDeclID.
explicit operator LocalDeclID() const { return LocalDeclID(this->ID); }
};

/// A helper iterator adaptor to convert the iterators to
/// `SmallVector<SomeDeclID>` to the iterators to `SmallVector<OtherDeclID>`.
template <class FromTy, class ToTy>
class DeclIDIterator
: public llvm::iterator_adaptor_base<DeclIDIterator<FromTy, ToTy>,
const FromTy *,
std::forward_iterator_tag, ToTy> {
public:
DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {}

DeclIDIterator(const FromTy *ID)
: DeclIDIterator::iterator_adaptor_base(ID) {}

ToTy operator*() const { return ToTy(*this->I); }

bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; }
};

} // namespace clang

namespace llvm {
template <> struct DenseMapInfo<clang::GlobalDeclID> {
using GlobalDeclID = clang::GlobalDeclID;
using DeclID = GlobalDeclID::DeclID;

static GlobalDeclID getEmptyKey() {
return GlobalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
}

static GlobalDeclID getTombstoneKey() {
return GlobalDeclID(DenseMapInfo<DeclID>::getTombstoneKey());
}

static unsigned getHashValue(const GlobalDeclID &Key) {
return DenseMapInfo<DeclID>::getHashValue(Key.get());
}

static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) {
return L == R;
}
};

} // namespace llvm

#endif
30 changes: 18 additions & 12 deletions clang/include/clang/AST/DeclObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ObjCImplementationControl impControl = ObjCImplementationControl::None,
bool HasRelatedResultType = false);

static ObjCMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

ObjCMethodDecl *getCanonicalDecl() override;
const ObjCMethodDecl *getCanonicalDecl() const {
Expand Down Expand Up @@ -614,7 +614,8 @@ class ObjCTypeParamDecl : public TypedefNameDecl {
IdentifierInfo *name,
SourceLocation colonLoc,
TypeSourceInfo *boundInfo);
static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, DeclID ID);
static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx,
GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -789,7 +790,7 @@ class ObjCPropertyDecl : public NamedDecl {
TypeSourceInfo *TSI,
PropertyControl propControl = None);

static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; }
Expand Down Expand Up @@ -1279,7 +1280,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc = SourceLocation(), bool isInternal = false);

static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, DeclID ID);
static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C,
GlobalDeclID ID);

/// Retrieve the type parameters of this class.
///
Expand Down Expand Up @@ -1969,7 +1971,7 @@ class ObjCIvarDecl : public FieldDecl {
TypeSourceInfo *TInfo, AccessControl ac,
Expr *BW = nullptr, bool synthesized = false);

static ObjCIvarDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Return the class interface that this ivar is logically contained
/// in; this is either the interface where the ivar was declared, or the
Expand Down Expand Up @@ -2039,7 +2041,8 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW);

static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Expand Down Expand Up @@ -2142,7 +2145,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
SourceLocation atStartLoc,
ObjCProtocolDecl *PrevDecl);

static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

const ObjCProtocolList &getReferencedProtocols() const {
assert(hasDefinition() && "No definition available!");
Expand Down Expand Up @@ -2361,7 +2364,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc = SourceLocation(),
SourceLocation IvarRBraceLoc = SourceLocation());
static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
Expand Down Expand Up @@ -2558,7 +2561,8 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface, SourceLocation nameLoc,
SourceLocation atStartLoc, SourceLocation CategoryNameLoc);
static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

ObjCCategoryDecl *getCategoryDecl() const;

Expand Down Expand Up @@ -2640,7 +2644,8 @@ class ObjCImplementationDecl : public ObjCImplDecl {
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation());

static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCImplementationDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

/// init_iterator - Iterates through the ivar initializer list.
using init_iterator = CXXCtorInitializer **;
Expand Down Expand Up @@ -2780,7 +2785,7 @@ class ObjCCompatibleAliasDecl : public NamedDecl {
ObjCInterfaceDecl* aliasedClass);

static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
GlobalDeclID ID);

const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
Expand Down Expand Up @@ -2851,7 +2856,8 @@ class ObjCPropertyImplDecl : public Decl {
ObjCIvarDecl *ivarDecl,
SourceLocation ivarLoc);

static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down
17 changes: 9 additions & 8 deletions clang/include/clang/AST/DeclOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ template <typename U> class OMPDeclarativeDirective : public U {
}

template <typename T, typename... Params>
static T *createEmptyDirective(const ASTContext &C, unsigned ID,
static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID,
unsigned NumClauses, unsigned NumChildren,
Params &&... P) {
auto *Inst = new (C, ID, size(NumClauses, NumChildren))
Expand Down Expand Up @@ -133,7 +133,7 @@ class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
SourceLocation L,
ArrayRef<Expr *> VL);
static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
DeclID ID, unsigned N);
GlobalDeclID ID, unsigned N);

typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
Expand Down Expand Up @@ -214,7 +214,7 @@ class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
/// Create deserialized declare reduction node.
static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
GlobalDeclID ID);

/// Get combiner expression of the declare reduction construct.
Expr *getCombiner() { return Combiner; }
Expand Down Expand Up @@ -318,8 +318,8 @@ class OMPDeclareMapperDecl final : public OMPDeclarativeDirective<ValueDecl>,
ArrayRef<OMPClause *> Clauses,
OMPDeclareMapperDecl *PrevDeclInScope);
/// Creates deserialized declare mapper node.
static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, DeclID ID,
unsigned N);
static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID, unsigned N);

using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
Expand Down Expand Up @@ -397,7 +397,8 @@ class OMPCapturedExprDecl final : public VarDecl {
IdentifierInfo *Id, QualType T,
SourceLocation StartLoc);

static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY;

Expand Down Expand Up @@ -427,7 +428,7 @@ class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, ArrayRef<OMPClause *> CL);
/// Create deserialized requires node.
static OMPRequiresDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned N);

using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
Expand Down Expand Up @@ -495,7 +496,7 @@ class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, ArrayRef<Expr *> VL,
ArrayRef<OMPClause *> CL);
static OMPAllocateDecl *CreateDeserialized(ASTContext &C, DeclID ID,
static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned NVars, unsigned NClauses);

typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
Expand Down
50 changes: 25 additions & 25 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
///
/// The first value in the array is the number of specializations/partial
/// specializations that follow.
Decl::DeclID *LazySpecializations = nullptr;
GlobalDeclID *LazySpecializations = nullptr;

/// The set of "injected" template arguments used within this
/// template.
Expand Down Expand Up @@ -1087,7 +1087,8 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
NamedDecl *Decl);

/// Create an empty function template node.
static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static FunctionTemplateDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Expand Down Expand Up @@ -1204,9 +1205,9 @@ class TemplateTypeParmDecl final : public TypeDecl,
bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
std::optional<unsigned> NumExpanded = std::nullopt);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
DeclID ID);
GlobalDeclID ID);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
DeclID ID,
GlobalDeclID ID,
bool HasTypeConstraint);

/// Whether this template type parameter was declared with
Expand Down Expand Up @@ -1413,11 +1414,10 @@ class NonTypeTemplateParmDecl final
QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
ArrayRef<TypeSourceInfo *> ExpandedTInfos);

static NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
DeclID ID,
bool HasTypeConstraint);
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
DeclID ID,
GlobalDeclID ID,
unsigned NumExpandedTypes,
bool HasTypeConstraint);

Expand Down Expand Up @@ -1632,10 +1632,9 @@ class TemplateTemplateParmDecl final
ArrayRef<TemplateParameterList *> Expansions);

static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
DeclID ID,
unsigned NumExpansions);
GlobalDeclID ID);
static TemplateTemplateParmDecl *
CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);

using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
Expand Down Expand Up @@ -1857,8 +1856,8 @@ class ClassTemplateSpecializationDecl
ClassTemplateDecl *SpecializedTemplate,
ArrayRef<TemplateArgument> Args,
ClassTemplateSpecializationDecl *PrevDecl);
static ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext &C, DeclID ID);
static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
bool Qualified) const override;
Expand Down Expand Up @@ -2110,7 +2109,7 @@ class ClassTemplatePartialSpecializationDecl
ClassTemplatePartialSpecializationDecl *PrevDecl);

static ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext &C, DeclID ID);
CreateDeserialized(ASTContext &C, GlobalDeclID ID);

ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
return cast<ClassTemplatePartialSpecializationDecl>(
Expand Down Expand Up @@ -2306,7 +2305,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
NamedDecl *Decl);

/// Create an empty class template node.
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
Expand Down Expand Up @@ -2472,7 +2471,7 @@ class FriendTemplateDecl : public Decl {
MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend,
SourceLocation FriendLoc);

static FriendTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// If this friend declaration names a templated type (or
/// a dependent member type of a templated type), return that
Expand Down Expand Up @@ -2573,7 +2572,8 @@ class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
NamedDecl *Decl);

/// Create an empty alias template node.
static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);

// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Expand Down Expand Up @@ -2670,7 +2670,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
TypeSourceInfo *TInfo, StorageClass S,
ArrayRef<TemplateArgument> Args);
static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
GlobalDeclID ID);

void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
bool Qualified) const override;
Expand Down Expand Up @@ -2900,8 +2900,8 @@ class VarTemplatePartialSpecializationDecl
TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args,
const TemplateArgumentListInfo &ArgInfos);

static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
static VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext &C, GlobalDeclID ID);

VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
return cast<VarTemplatePartialSpecializationDecl>(
Expand Down Expand Up @@ -3078,7 +3078,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
VarDecl *Decl);

/// Create an empty variable template node.
static VarTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

/// Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
Expand Down Expand Up @@ -3183,7 +3183,7 @@ class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
Expr *ConstraintExpr);
static ConceptDecl *CreateDeserialized(ASTContext &C, DeclID ID);
static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

Expr *getConstraintExpr() const {
return ConstraintExpr;
Expand Down Expand Up @@ -3232,7 +3232,7 @@ class ImplicitConceptSpecializationDecl final
Create(const ASTContext &C, DeclContext *DC, SourceLocation SL,
ArrayRef<TemplateArgument> ConvertedArgs);
static ImplicitConceptSpecializationDecl *
CreateDeserialized(const ASTContext &C, DeclID ID,
CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
unsigned NumTemplateArgs);

ArrayRef<TemplateArgument> getTemplateArguments() const {
Expand Down Expand Up @@ -3275,7 +3275,7 @@ class TemplateParamObjectDecl : public ValueDecl,
static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
const APValue &V);
static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
DeclID ID);
GlobalDeclID ID);

/// Only ASTContext::getTemplateParamObjectDecl and deserialization
/// create these.
Expand Down
269 changes: 269 additions & 0 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6610,6 +6610,275 @@ class TypoExpr : public Expr {

};

/// This class represents BOTH the OpenMP Array Section and OpenACC 'subarray',
/// with a boolean differentiator.
/// OpenMP 5.0 [2.1.5, Array Sections].
/// To specify an array section in an OpenMP construct, array subscript
/// expressions are extended with the following syntax:
/// \code
/// [ lower-bound : length : stride ]
/// [ lower-bound : length : ]
/// [ lower-bound : length ]
/// [ lower-bound : : stride ]
/// [ lower-bound : : ]
/// [ lower-bound : ]
/// [ : length : stride ]
/// [ : length : ]
/// [ : length ]
/// [ : : stride ]
/// [ : : ]
/// [ : ]
/// \endcode
/// The array section must be a subset of the original array.
/// Array sections are allowed on multidimensional arrays. Base language array
/// subscript expressions can be used to specify length-one dimensions of
/// multidimensional array sections.
/// Each of the lower-bound, length, and stride expressions if specified must be
/// an integral type expressions of the base language. When evaluated
/// they represent a set of integer values as follows:
/// \code
/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
/// lower-bound + ((length - 1) * stride) }
/// \endcode
/// The lower-bound and length must evaluate to non-negative integers.
/// The stride must evaluate to a positive integer.
/// When the size of the array dimension is not known, the length must be
/// specified explicitly.
/// When the stride is absent it defaults to 1.
/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
/// where size is the size of the array dimension. When the lower-bound is
/// absent it defaults to 0.
///
///
/// OpenACC 3.3 [2.7.1 Data Specification in Data Clauses]
/// In C and C++, a subarray is an array name followed by an extended array
/// range specification in brackets, with start and length, such as
///
/// AA[2:n]
///
/// If the lower bound is missing, zero is used. If the length is missing and
/// the array has known size, the size of the array is used; otherwise the
/// length is required. The subarray AA[2:n] means elements AA[2], AA[3], . . .
/// , AA[2+n-1]. In C and C++, a two dimensional array may be declared in at
/// least four ways:
///
/// -Statically-sized array: float AA[100][200];
/// -Pointer to statically sized rows: typedef float row[200]; row* BB;
/// -Statically-sized array of pointers: float* CC[200];
/// -Pointer to pointers: float** DD;
///
/// Each dimension may be statically sized, or a pointer to dynamically
/// allocated memory. Each of these may be included in a data clause using
/// subarray notation to specify a rectangular array:
///
/// -AA[2:n][0:200]
/// -BB[2:n][0:m]
/// -CC[2:n][0:m]
/// -DD[2:n][0:m]
///
/// Multidimensional rectangular subarrays in C and C++ may be specified for any
/// array with any combination of statically-sized or dynamically-allocated
/// dimensions. For statically sized dimensions, all dimensions except the first
/// must specify the whole extent to preserve the contiguous data restriction,
/// discussed below. For dynamically allocated dimensions, the implementation
/// will allocate pointers in device memory corresponding to the pointers in
/// local memory and will fill in those pointers as appropriate.
///
/// In Fortran, a subarray is an array name followed by a comma-separated list
/// of range specifications in parentheses, with lower and upper bound
/// subscripts, such as
///
/// arr(1:high,low:100)
///
/// If either the lower or upper bounds are missing, the declared or allocated
/// bounds of the array, if known, are used. All dimensions except the last must
/// specify the whole extent, to preserve the contiguous data restriction,
/// discussed below.
///
/// Restrictions
///
/// -In Fortran, the upper bound for the last dimension of an assumed-size dummy
/// array must be specified.
///
/// -In C and C++, the length for dynamically allocated dimensions of an array
/// must be explicitly specified.
///
/// -In C and C++, modifying pointers in pointer arrays during the data
/// lifetime, either on the host or on the device, may result in undefined
/// behavior.
///
/// -If a subarray appears in a data clause, the implementation may choose to
/// allocate memory for only that subarray on the accelerator.
///
/// -In Fortran, array pointers may appear, but pointer association is not
/// preserved in device memory.
///
/// -Any array or subarray in a data clause, including Fortran array pointers,
/// must be a contiguous section of memory, except for dynamic multidimensional
/// C arrays.
///
/// -In C and C++, if a variable or array of composite type appears, all the
/// data members of the struct or class are allocated and copied, as
/// appropriate. If a composite member is a pointer type, the data addressed by
/// that pointer are not implicitly copied.
///
/// -In Fortran, if a variable or array of composite type appears, all the
/// members of that derived type are allocated and copied, as appropriate. If
/// any member has the allocatable or pointer attribute, the data accessed
/// through that member are not copied.
///
/// -If an expression is used in a subscript or subarray expression in a clause
/// on a data construct, the same value is used when copying data at the end of
/// the data region, even if the values of variables in the expression change
/// during the data region.
class ArraySectionExpr : public Expr {
friend class ASTStmtReader;
friend class ASTStmtWriter;

public:
enum ArraySectionType { OMPArraySection, OpenACCArraySection };

private:
enum {
BASE,
LOWER_BOUND,
LENGTH,
STRIDE,
END_EXPR,
OPENACC_END_EXPR = STRIDE
};

ArraySectionType ASType = OMPArraySection;
Stmt *SubExprs[END_EXPR] = {nullptr};
SourceLocation ColonLocFirst;
SourceLocation ColonLocSecond;
SourceLocation RBracketLoc;

public:
// Constructor for OMP array sections, which include a 'stride'.
ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
QualType Type, ExprValueKind VK, ExprObjectKind OK,
SourceLocation ColonLocFirst, SourceLocation ColonLocSecond,
SourceLocation RBracketLoc)
: Expr(ArraySectionExprClass, Type, VK, OK), ASType(OMPArraySection),
ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
RBracketLoc(RBracketLoc) {
setBase(Base);
setLowerBound(LowerBound);
setLength(Length);
setStride(Stride);
setDependence(computeDependence(this));
}

// Constructor for OpenACC sub-arrays, which do not permit a 'stride'.
ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
ExprValueKind VK, ExprObjectKind OK, SourceLocation ColonLoc,
SourceLocation RBracketLoc)
: Expr(ArraySectionExprClass, Type, VK, OK), ASType(OpenACCArraySection),
ColonLocFirst(ColonLoc), RBracketLoc(RBracketLoc) {
setBase(Base);
setLowerBound(LowerBound);
setLength(Length);
setDependence(computeDependence(this));
}

/// Create an empty array section expression.
explicit ArraySectionExpr(EmptyShell Shell)
: Expr(ArraySectionExprClass, Shell) {}

/// Return original type of the base expression for array section.
static QualType getBaseOriginalType(const Expr *Base);

static bool classof(const Stmt *T) {
return T->getStmtClass() == ArraySectionExprClass;
}

bool isOMPArraySection() const { return ASType == OMPArraySection; }
bool isOpenACCArraySection() const { return ASType == OpenACCArraySection; }

/// Get base of the array section.
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }

/// Get lower bound of array section.
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
const Expr *getLowerBound() const {
return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
}

/// Get length of array section.
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }

/// Get stride of array section.
Expr *getStride() {
assert(ASType != OpenACCArraySection &&
"Stride not valid in OpenACC subarrays");
return cast_or_null<Expr>(SubExprs[STRIDE]);
}

const Expr *getStride() const {
assert(ASType != OpenACCArraySection &&
"Stride not valid in OpenACC subarrays");
return cast_or_null<Expr>(SubExprs[STRIDE]);
}

SourceLocation getBeginLoc() const LLVM_READONLY {
return getBase()->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }

SourceLocation getColonLocFirst() const { return ColonLocFirst; }
SourceLocation getColonLocSecond() const {
assert(ASType != OpenACCArraySection &&
"second colon for stride not valid in OpenACC subarrays");
return ColonLocSecond;
}
SourceLocation getRBracketLoc() const { return RBracketLoc; }

SourceLocation getExprLoc() const LLVM_READONLY {
return getBase()->getExprLoc();
}

child_range children() {
return child_range(
&SubExprs[BASE],
&SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]);
}

const_child_range children() const {
return const_child_range(
&SubExprs[BASE],
&SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]);
}

private:
/// Set base of the array section.
void setBase(Expr *E) { SubExprs[BASE] = E; }

/// Set lower bound of the array section.
void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }

/// Set length of the array section.
void setLength(Expr *E) { SubExprs[LENGTH] = E; }

/// Set length of the array section.
void setStride(Expr *E) {
assert(ASType != OpenACCArraySection &&
"Stride not valid in OpenACC subarrays");
SubExprs[STRIDE] = E;
}

void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }

void setColonLocSecond(SourceLocation L) {
assert(ASType != OpenACCArraySection &&
"second colon for stride not valid in OpenACC subarrays");
ColonLocSecond = L;
}
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
};

/// Frontend produces RecoveryExprs on semantic errors that prevent creating
/// other well-formed expressions. E.g. when type-checking of a binary operator
/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,8 @@ class CXXTemporary {
/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
/// }
/// \endcode
///
/// Destructor might be null if destructor declaration is not valid.
class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp = nullptr;
Stmt *SubExpr = nullptr;
Expand Down
124 changes: 0 additions & 124 deletions clang/include/clang/AST/ExprOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,130 +17,6 @@
#include "clang/AST/Expr.h"

namespace clang {
/// OpenMP 5.0 [2.1.5, Array Sections].
/// To specify an array section in an OpenMP construct, array subscript
/// expressions are extended with the following syntax:
/// \code
/// [ lower-bound : length : stride ]
/// [ lower-bound : length : ]
/// [ lower-bound : length ]
/// [ lower-bound : : stride ]
/// [ lower-bound : : ]
/// [ lower-bound : ]
/// [ : length : stride ]
/// [ : length : ]
/// [ : length ]
/// [ : : stride ]
/// [ : : ]
/// [ : ]
/// \endcode
/// The array section must be a subset of the original array.
/// Array sections are allowed on multidimensional arrays. Base language array
/// subscript expressions can be used to specify length-one dimensions of
/// multidimensional array sections.
/// Each of the lower-bound, length, and stride expressions if specified must be
/// an integral type expressions of the base language. When evaluated
/// they represent a set of integer values as follows:
/// \code
/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
/// lower-bound + ((length - 1) * stride) }
/// \endcode
/// The lower-bound and length must evaluate to non-negative integers.
/// The stride must evaluate to a positive integer.
/// When the size of the array dimension is not known, the length must be
/// specified explicitly.
/// When the stride is absent it defaults to 1.
/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
/// where size is the size of the array dimension. When the lower-bound is
/// absent it defaults to 0.
class OMPArraySectionExpr : public Expr {
enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
Stmt *SubExprs[END_EXPR];
SourceLocation ColonLocFirst;
SourceLocation ColonLocSecond;
SourceLocation RBracketLoc;

public:
OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
QualType Type, ExprValueKind VK, ExprObjectKind OK,
SourceLocation ColonLocFirst,
SourceLocation ColonLocSecond, SourceLocation RBracketLoc)
: Expr(OMPArraySectionExprClass, Type, VK, OK),
ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
RBracketLoc(RBracketLoc) {
SubExprs[BASE] = Base;
SubExprs[LOWER_BOUND] = LowerBound;
SubExprs[LENGTH] = Length;
SubExprs[STRIDE] = Stride;
setDependence(computeDependence(this));
}

/// Create an empty array section expression.
explicit OMPArraySectionExpr(EmptyShell Shell)
: Expr(OMPArraySectionExprClass, Shell) {}

/// An array section can be written only as Base[LowerBound:Length].

/// Get base of the array section.
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
/// Set base of the array section.
void setBase(Expr *E) { SubExprs[BASE] = E; }

/// Return original type of the base expression for array section.
static QualType getBaseOriginalType(const Expr *Base);

/// Get lower bound of array section.
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
const Expr *getLowerBound() const {
return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
}
/// Set lower bound of the array section.
void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }

/// Get length of array section.
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
/// Set length of the array section.
void setLength(Expr *E) { SubExprs[LENGTH] = E; }

/// Get stride of array section.
Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); }
const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); }
/// Set length of the array section.
void setStride(Expr *E) { SubExprs[STRIDE] = E; }

SourceLocation getBeginLoc() const LLVM_READONLY {
return getBase()->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }

SourceLocation getColonLocFirst() const { return ColonLocFirst; }
void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }

SourceLocation getColonLocSecond() const { return ColonLocSecond; }
void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; }

SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }

SourceLocation getExprLoc() const LLVM_READONLY {
return getBase()->getExprLoc();
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPArraySectionExprClass;
}

child_range children() {
return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}

const_child_range children() const {
return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}
};

/// An explicit cast in C or a C-style cast in C++, which uses the syntax
/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
class OMPArrayShapingExpr final
Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// passes back decl sets as VisibleDeclaration objects.
///
/// The default implementation of this method is a no-op.
virtual Decl *GetExternalDecl(Decl::DeclID ID);
virtual Decl *GetExternalDecl(GlobalDeclID ID);

/// Resolve a selector ID into a selector.
///
Expand Down Expand Up @@ -375,7 +375,7 @@ struct LazyOffsetPtr {
if (isOffset()) {
assert(Source &&
"Cannot deserialize a lazy pointer without an AST source");
Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
Ptr = reinterpret_cast<uint64_t>((Source->*Get)(OffsT(Ptr >> 1)));
}
return reinterpret_cast<T*>(Ptr);
}
Expand Down Expand Up @@ -579,7 +579,7 @@ using LazyDeclStmtPtr =

/// A lazy pointer to a declaration.
using LazyDeclPtr =
LazyOffsetPtr<Decl, Decl::DeclID, &ExternalASTSource::GetExternalDecl>;
LazyOffsetPtr<Decl, GlobalDeclID, &ExternalASTSource::GetExternalDecl>;

/// A lazy pointer to a set of CXXCtorInitializers.
using LazyCXXCtorInitializersPtr =
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/NestedNameSpecifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ class NestedNameSpecifierLoc {
explicit operator bool() const { return Qualifier; }

/// Evaluates true when this nested-name-specifier location is
/// empty.
/// non-empty.
bool hasQualifier() const { return Qualifier; }

/// Retrieve the nested-name-specifier to which this instance
Expand Down
91 changes: 64 additions & 27 deletions clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,51 +156,50 @@ class OpenACCSelfClause : public OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
};

/// Represents a clause that has one or more IntExprs. It does not own the
/// IntExprs, but provides 'children' and other accessors.
class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
MutableArrayRef<Expr *> IntExprs;
/// Represents a clause that has one or more expressions associated with it.
class OpenACCClauseWithExprs : public OpenACCClauseWithParams {
MutableArrayRef<Expr *> Exprs;

protected:
OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {}

/// Used only for initialization, the leaf class can initialize this to
/// trailing storage.
void setIntExprs(MutableArrayRef<Expr *> NewIntExprs) {
assert(IntExprs.empty() && "Cannot change IntExprs list");
IntExprs = NewIntExprs;
void setExprs(MutableArrayRef<Expr *> NewExprs) {
assert(Exprs.empty() && "Cannot change Exprs list");
Exprs = NewExprs;
}

/// Gets the entire list of integer expressions, but leave it to the
/// Gets the entire list of expressions, but leave it to the
/// individual clauses to expose this how they'd like.
llvm::ArrayRef<Expr *> getIntExprs() const { return IntExprs; }
llvm::ArrayRef<Expr *> getExprs() const { return Exprs; }

public:
child_range children() {
return child_range(reinterpret_cast<Stmt **>(IntExprs.begin()),
reinterpret_cast<Stmt **>(IntExprs.end()));
return child_range(reinterpret_cast<Stmt **>(Exprs.begin()),
reinterpret_cast<Stmt **>(Exprs.end()));
}

const_child_range children() const {
child_range Children =
const_cast<OpenACCClauseWithIntExprs *>(this)->children();
const_cast<OpenACCClauseWithExprs *>(this)->children();
return const_child_range(Children.begin(), Children.end());
}
};

class OpenACCNumGangsClause final
: public OpenACCClauseWithIntExprs,
: public OpenACCClauseWithExprs,
public llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {

OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
: OpenACCClauseWithIntExprs(OpenACCClauseKind::NumGangs, BeginLoc,
LParenLoc, EndLoc) {
: OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc,
EndLoc) {
std::uninitialized_copy(IntExprs.begin(), IntExprs.end(),
getTrailingObjects<Expr *>());
setIntExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), IntExprs.size()));
}

public:
Expand All @@ -209,35 +208,35 @@ class OpenACCNumGangsClause final
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);

llvm::ArrayRef<Expr *> getIntExprs() {
return OpenACCClauseWithIntExprs::getIntExprs();
return OpenACCClauseWithExprs::getExprs();
}

llvm::ArrayRef<Expr *> getIntExprs() const {
return OpenACCClauseWithIntExprs::getIntExprs();
return OpenACCClauseWithExprs::getExprs();
}
};

/// Represents one of a handful of clauses that have a single integer
/// expression.
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs {
Expr *IntExpr;

protected:
OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, Expr *IntExpr,
SourceLocation EndLoc)
: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, EndLoc),
: OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc),
IntExpr(IntExpr) {
setIntExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
setExprs(MutableArrayRef<Expr *>{&this->IntExpr, 1});
}

public:
bool hasIntExpr() const { return !getIntExprs().empty(); }
bool hasIntExpr() const { return !getExprs().empty(); }
const Expr *getIntExpr() const {
return hasIntExpr() ? getIntExprs()[0] : nullptr;
return hasIntExpr() ? getExprs()[0] : nullptr;
}

Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; };
Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; };
};

class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
Expand All @@ -261,6 +260,40 @@ class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr {
Expr *IntExpr, SourceLocation EndLoc);
};

/// Represents a clause with one or more 'var' objects, represented as an expr,
/// as its arguments. Var-list is expected to be stored in trailing storage.
/// For now, we're just storing the original expression in its entirety, unlike
/// OMP which has to do a bunch of work to create a private.
class OpenACCClauseWithVarList : public OpenACCClauseWithExprs {
protected:
OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {}

public:
ArrayRef<Expr *> getVarList() { return getExprs(); }
ArrayRef<Expr *> getVarList() const { return getExprs(); }
};

class OpenACCPrivateClause final
: public OpenACCClauseWithVarList,
public llvm::TrailingObjects<OpenACCPrivateClause, Expr *> {

OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
: OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc,
LParenLoc, EndLoc) {
std::uninitialized_copy(VarList.begin(), VarList.end(),
getTrailingObjects<Expr *>());
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
}

public:
static OpenACCPrivateClause *
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
};

template <class Impl> class OpenACCClauseVisitor {
Impl &getDerived() { return static_cast<Impl &>(*this); }

Expand Down Expand Up @@ -299,6 +332,9 @@ template <class Impl> class OpenACCClauseVisitor {
class OpenACCClausePrinter final
: public OpenACCClauseVisitor<OpenACCClausePrinter> {
raw_ostream &OS;
const PrintingPolicy &Policy;

void printExpr(const Expr *E);

public:
void VisitClauseList(ArrayRef<const OpenACCClause *> List) {
Expand All @@ -309,7 +345,8 @@ class OpenACCClausePrinter final
OS << ' ';
}
}
OpenACCClausePrinter(raw_ostream &OS) : OS(OS) {}
OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
: OS(OS), Policy(Policy) {}

#define VISIT_CLAUSE(CLAUSE_NAME) \
void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
Expand Down
Loading