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
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/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2740,7 +2740,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
DEF_TRAVERSE_STMT(ArraySectionExpr, {})
DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
DEF_TRAVERSE_STMT(OMPIteratorExpr, {})

Expand Down
254 changes: 230 additions & 24 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/PointerAuthOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/Visibility.h"
Expand Down Expand Up @@ -139,6 +141,174 @@ using CanQualType = CanQual<Type>;
#define TYPE(Class, Base) class Class##Type;
#include "clang/AST/TypeNodes.inc"

/// Pointer-authentication qualifiers.
class PointerAuthQualifier {
enum : uint32_t {
EnabledShift = 0,
EnabledBits = 1,
EnabledMask = 1 << EnabledShift,
AddressDiscriminatedShift = EnabledShift + EnabledBits,
AddressDiscriminatedBits = 1,
AddressDiscriminatedMask = 1 << AddressDiscriminatedShift,
AuthenticationModeShift =
AddressDiscriminatedShift + AddressDiscriminatedBits,
AuthenticationModeBits = 2,
AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1)
<< AuthenticationModeShift,
IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits,
IsaPointerBits = 1,
IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift,
AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits,
AuthenticatesNullValuesBits = 1,
AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1)
<< AuthenticatesNullValuesShift,
KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits,
KeyBits = 10,
KeyMask = ((1 << KeyBits) - 1) << KeyShift,
DiscriminatorShift = KeyShift + KeyBits,
DiscriminatorBits = 16,
DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift,
};

// bits: |0 |1 |2..3 |4 |
// |Enabled|Address|AuthenticationMode|ISA pointer|
// bits: |5 |6..15| 16...31 |
// |AuthenticatesNull|Key |Discriminator|
uint32_t Data = 0;

// The following static assertions check that each of the 32 bits is present
// exactly in one of the constants.
static_assert((EnabledBits + AddressDiscriminatedBits +
AuthenticationModeBits + IsaPointerBits +
AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) ==
32,
"PointerAuthQualifier should be exactly 32 bits");
static_assert((EnabledMask + AddressDiscriminatedMask +
AuthenticationModeMask + IsaPointerMask +
AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) ==
0xFFFFFFFF,
"All masks should cover the entire bits");
static_assert((EnabledMask ^ AddressDiscriminatedMask ^
AuthenticationModeMask ^ IsaPointerMask ^
AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) ==
0xFFFFFFFF,
"All masks should cover the entire bits");

PointerAuthQualifier(unsigned Key, bool IsAddressDiscriminated,
unsigned ExtraDiscriminator,
PointerAuthenticationMode AuthenticationMode,
bool IsIsaPointer, bool AuthenticatesNullValues)
: Data(EnabledMask |
(IsAddressDiscriminated
? llvm::to_underlying(AddressDiscriminatedMask)
: 0) |
(Key << KeyShift) |
(llvm::to_underlying(AuthenticationMode)
<< AuthenticationModeShift) |
(ExtraDiscriminator << DiscriminatorShift) |
(IsIsaPointer << IsaPointerShift) |
(AuthenticatesNullValues << AuthenticatesNullValuesShift)) {
assert(Key <= KeyNoneInternal);
assert(ExtraDiscriminator <= MaxDiscriminator);
assert((Data == 0) ==
(getAuthenticationMode() == PointerAuthenticationMode::None));
}

public:
enum {
KeyNoneInternal = (1u << KeyBits) - 1,

/// The maximum supported pointer-authentication key.
MaxKey = KeyNoneInternal - 1,

/// The maximum supported pointer-authentication discriminator.
MaxDiscriminator = (1u << DiscriminatorBits) - 1
};

public:
PointerAuthQualifier() = default;

static PointerAuthQualifier
Create(unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator,
PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer,
bool AuthenticatesNullValues) {
if (Key == PointerAuthKeyNone)
Key = KeyNoneInternal;
assert(Key <= KeyNoneInternal && "out-of-range key value");
return PointerAuthQualifier(Key, IsAddressDiscriminated, ExtraDiscriminator,
AuthenticationMode, IsIsaPointer,
AuthenticatesNullValues);
}

bool isPresent() const {
assert((Data == 0) ==
(getAuthenticationMode() == PointerAuthenticationMode::None));
return Data != 0;
}

explicit operator bool() const { return isPresent(); }

unsigned getKey() const {
assert(isPresent());
return (Data & KeyMask) >> KeyShift;
}

bool hasKeyNone() const { return isPresent() && getKey() == KeyNoneInternal; }

bool isAddressDiscriminated() const {
assert(isPresent());
return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift;
}

unsigned getExtraDiscriminator() const {
assert(isPresent());
return (Data >> DiscriminatorShift);
}

PointerAuthenticationMode getAuthenticationMode() const {
return PointerAuthenticationMode((Data & AuthenticationModeMask) >>
AuthenticationModeShift);
}

bool isIsaPointer() const {
assert(isPresent());
return (Data & IsaPointerMask) >> IsaPointerShift;
}

bool authenticatesNullValues() const {
assert(isPresent());
return (Data & AuthenticatesNullValuesMask) >> AuthenticatesNullValuesShift;
}

PointerAuthQualifier withoutKeyNone() const {
return hasKeyNone() ? PointerAuthQualifier() : *this;
}

friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
return Lhs.Data == Rhs.Data;
}
friend bool operator!=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
return Lhs.Data != Rhs.Data;
}

bool isEquivalent(PointerAuthQualifier Other) const {
return withoutKeyNone() == Other.withoutKeyNone();
}

uint32_t getAsOpaqueValue() const { return Data; }

// Deserialize pointer-auth qualifiers from an opaque representation.
static PointerAuthQualifier fromOpaqueValue(uint32_t Opaque) {
PointerAuthQualifier Result;
Result.Data = Opaque;
assert((Result.Data == 0) ==
(Result.getAuthenticationMode() == PointerAuthenticationMode::None));
return Result;
}

void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Data); }
};

/// The collection of all-type qualifiers we support.
/// Clang supports five independent qualifiers:
/// * C99: const, volatile, and restrict
Expand All @@ -147,8 +317,9 @@ using CanQualType = CanQual<Type>;
/// * Objective C: the GC attributes (none, weak, or strong)
class Qualifiers {
public:
enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
Const = 0x1,
enum TQ : uint64_t {
// NOTE: These flags must be kept in sync with DeclSpec::TQ.
Const = 0x1,
Restrict = 0x2,
Volatile = 0x4,
CVRMask = Const | Volatile | Restrict
Expand Down Expand Up @@ -182,7 +353,7 @@ class Qualifiers {
OCL_Autoreleasing
};

enum {
enum : uint64_t {
/// The maximum supported address space number.
/// 23 bits should be enough for anyone.
MaxAddressSpace = 0x7fffffu,
Expand All @@ -197,16 +368,25 @@ class Qualifiers {
/// Returns the common set of qualifiers while removing them from
/// the given sets.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
Qualifiers Q;
PointerAuthQualifier LPtrAuth = L.getPointerAuth();
if (LPtrAuth.isPresent() &&
LPtrAuth.getKey() != PointerAuthQualifier::KeyNoneInternal &&
LPtrAuth == R.getPointerAuth()) {
Q.setPointerAuth(LPtrAuth);
PointerAuthQualifier Empty;
L.setPointerAuth(Empty);
R.setPointerAuth(Empty);
}

// If both are only CVR-qualified, bit operations are sufficient.
if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
Qualifiers Q;
Q.Mask = L.Mask & R.Mask;
L.Mask &= ~Q.Mask;
R.Mask &= ~Q.Mask;
return Q;
}

Qualifiers Q;
unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
Q.addCVRQualifiers(CommonCRV);
L.removeCVRQualifiers(CommonCRV);
Expand Down Expand Up @@ -251,16 +431,14 @@ class Qualifiers {
}

// Deserialize qualifiers from an opaque representation.
static Qualifiers fromOpaqueValue(unsigned opaque) {
static Qualifiers fromOpaqueValue(uint64_t opaque) {
Qualifiers Qs;
Qs.Mask = opaque;
return Qs;
}

// Serialize these qualifiers into an opaque representation.
unsigned getAsOpaqueValue() const {
return Mask;
}
uint64_t getAsOpaqueValue() const { return Mask; }

bool hasConst() const { return Mask & Const; }
bool hasOnlyConst() const { return Mask == Const; }
Expand Down Expand Up @@ -407,6 +585,20 @@ class Qualifiers {
setAddressSpace(space);
}

bool hasPointerAuth() const { return Mask & PtrAuthMask; }
PointerAuthQualifier getPointerAuth() const {
return PointerAuthQualifier::fromOpaqueValue(Mask >> PtrAuthShift);
}
void setPointerAuth(PointerAuthQualifier Q) {
Mask = (Mask & ~PtrAuthMask) |
(uint64_t(Q.getAsOpaqueValue()) << PtrAuthShift);
}
void removePointerAuth() { Mask &= ~PtrAuthMask; }
void addPointerAuth(PointerAuthQualifier Q) {
assert(Q.isPresent());
setPointerAuth(Q);
}

// Fast qualifiers are those that can be allocated directly
// on a QualType object.
bool hasFastQualifiers() const { return getFastQualifiers(); }
Expand Down Expand Up @@ -454,6 +646,8 @@ class Qualifiers {
addObjCGCAttr(Q.getObjCGCAttr());
if (Q.hasObjCLifetime())
addObjCLifetime(Q.getObjCLifetime());
if (Q.hasPointerAuth())
addPointerAuth(Q.getPointerAuth());
}
}

Expand All @@ -471,6 +665,8 @@ class Qualifiers {
removeObjCLifetime();
if (getAddressSpace() == Q.getAddressSpace())
removeAddressSpace();
if (getPointerAuth() == Q.getPointerAuth())
removePointerAuth();
}
}

Expand All @@ -483,6 +679,8 @@ class Qualifiers {
!hasObjCGCAttr() || !qs.hasObjCGCAttr());
assert(getObjCLifetime() == qs.getObjCLifetime() ||
!hasObjCLifetime() || !qs.hasObjCLifetime());
assert(!hasPointerAuth() || !qs.hasPointerAuth() ||
getPointerAuth() == qs.getPointerAuth());
Mask |= qs.Mask;
}

Expand Down Expand Up @@ -536,6 +734,8 @@ class Qualifiers {
// be changed.
(getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() ||
!other.hasObjCGCAttr()) &&
// Pointer-auth qualifiers must match exactly.
getPointerAuth() == other.getPointerAuth() &&
// ObjC lifetime qualifiers must match exactly.
getObjCLifetime() == other.getObjCLifetime() &&
// CVR qualifiers may subset.
Expand Down Expand Up @@ -605,24 +805,26 @@ class Qualifiers {
void print(raw_ostream &OS, const PrintingPolicy &Policy,
bool appendSpaceIfNonEmpty = false) const;

void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddInteger(Mask);
}
void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Mask); }

private:
// bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|
// |C R V|U|GCAttr|Lifetime|AddressSpace|
uint32_t Mask = 0;

static const uint32_t UMask = 0x8;
static const uint32_t UShift = 3;
static const uint32_t GCAttrMask = 0x30;
static const uint32_t GCAttrShift = 4;
static const uint32_t LifetimeMask = 0x1C0;
static const uint32_t LifetimeShift = 6;
static const uint32_t AddressSpaceMask =
// bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|32 ... 63|
// |C R V|U|GCAttr|Lifetime|AddressSpace| PtrAuth |
uint64_t Mask = 0;
static_assert(sizeof(PointerAuthQualifier) == sizeof(uint32_t),
"PointerAuthQualifier must be 32 bits");

static constexpr uint64_t UMask = 0x8;
static constexpr uint64_t UShift = 3;
static constexpr uint64_t GCAttrMask = 0x30;
static constexpr uint64_t GCAttrShift = 4;
static constexpr uint64_t LifetimeMask = 0x1C0;
static constexpr uint64_t LifetimeShift = 6;
static constexpr uint64_t AddressSpaceMask =
~(CVRMask | UMask | GCAttrMask | LifetimeMask);
static const uint32_t AddressSpaceShift = 9;
static constexpr uint64_t AddressSpaceShift = 9;
static constexpr uint64_t PtrAuthShift = 32;
static constexpr uint64_t PtrAuthMask = uint64_t(0xffffffff) << PtrAuthShift;
};

class QualifiersAndAtomic {
Expand Down Expand Up @@ -1242,6 +1444,10 @@ class QualType {
// true when Type is objc's weak and weak is enabled but ARC isn't.
bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;

PointerAuthQualifier getPointerAuth() const {
return getQualifiers().getPointerAuth();
}

enum PrimitiveDefaultInitializeKind {
/// The type does not fall into any of the following categories. Note that
/// this case is zero-valued so that values of this enum can be used as a
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -370,4 +370,7 @@ def warn_missing_symbol_graph_dir : Warning<
"Missing symbol graph output directory, defaulting to working directory">,
InGroup<ExtractAPIMisuse>;

def err_ast_action_on_llvm_ir : Error<
"cannot apply AST actions to LLVM IR file '%0'">,
DefaultFatal;
}
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11161,7 +11161,7 @@ def err_omp_declare_mapper_redefinition : Error<
"redefinition of user-defined mapper for type %0 with name %1">;
def err_omp_invalid_mapper: Error<
"cannot find a valid user-defined mapper for type %0 with name %1">;
def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;
def err_array_section_use : Error<"%select{OpenACC sub-array|OpenMP array section}0 is not allowed here">;
def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">;
def err_omp_iterator_use : Error<"OpenMP iterator is not allowed here">;
def err_omp_typecheck_section_value : Error<
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/FileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ class FileManager : public RefCountedBase<FileManager> {
///
unsigned NextFileUID;

/// Statistics gathered during the lifetime of the FileManager.
unsigned NumDirLookups = 0;
unsigned NumFileLookups = 0;
unsigned NumDirCacheMisses = 0;
unsigned NumFileCacheMisses = 0;

// Caching.
std::unique_ptr<FileSystemStatCache> StatCache;

Expand Down Expand Up @@ -341,6 +347,10 @@ class FileManager : public RefCountedBase<FileManager> {

public:
void PrintStats() const;

/// Import statistics from a child FileManager and add them to this current
/// FileManager.
void AddStats(const FileManager &Other);
};

} // end namespace clang
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ enum class ShaderStage {
Invalid,
};

enum class PointerAuthenticationMode : unsigned {
None,
Strip,
SignAndStrip,
SignAndAuth
};

/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
/// this large collection of bitfields is a trivial class type.
class LangOptionsBase {
Expand Down
23 changes: 23 additions & 0 deletions clang/include/clang/Basic/PointerAuthOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===--- PointerAuthOptions.h -----------------------------------*- 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 options for configuring pointer-auth technologies
// like ARMv8.3.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
#define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H

namespace clang {

constexpr unsigned PointerAuthKeyNone = -1;

} // end namespace clang

#endif
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def OffsetOfExpr : StmtNode<Expr>;
def UnaryExprOrTypeTraitExpr : StmtNode<Expr>;
def ArraySubscriptExpr : StmtNode<Expr>;
def MatrixSubscriptExpr : StmtNode<Expr>;
def OMPArraySectionExpr : StmtNode<Expr>;
def ArraySectionExpr : StmtNode<Expr>;
def OMPIteratorExpr : StmtNode<Expr>;
def CallExpr : StmtNode<Expr>;
def MemberExpr : StmtNode<Expr>;
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <cassert>
#include <optional>
#include <string>
#include <utility>
#include <vector>

namespace llvm {
Expand Down Expand Up @@ -1792,6 +1793,15 @@ class TargetInfo : public TransferrableTargetInfo,
/// Whether to support HIP image/texture API's.
virtual bool hasHIPImageSupport() const { return true; }

/// The first value in the pair is the minimum offset between two objects to
/// avoid false sharing (destructive interference). The second value in the
/// pair is maximum size of contiguous memory to promote true sharing
/// (constructive interference). Neither of these values are considered part
/// of the ABI and can be changed by targets at any time.
virtual std::pair<unsigned, unsigned> hardwareInterferenceSizes() const {
return std::make_pair(64, 64);
}

protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);
Expand Down
27 changes: 14 additions & 13 deletions clang/include/clang/Basic/arm_sve.td
Original file line number Diff line number Diff line change
Expand Up @@ -1961,19 +1961,20 @@ def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamin

// Standalone sve2.1 builtins
let TargetGuard = "sve2p1" in {
def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>;
def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>;
def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfdcsilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>;
def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>;
def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>;
def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>;
def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>;
def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>;

def SVFMAXNMQV: SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>;
def SVFMINNMQV: SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>;
def SVFMAXQV: SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>;
def SVFMINQV: SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>;
def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>;
def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>;
def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>;
def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>;
def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>;
def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>;
def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>;
def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>;

def SVFADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_faddqv", [IsReductionQV]>;
def SVFMAXNMQV : SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>;
def SVFMINNMQV : SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>;
def SVFMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>;
def SVFMINQV : SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>;
}

let TargetGuard = "sve2p1|sme2" in {
Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2615,6 +2615,11 @@ defm protect_parens : BoolFOption<"protect-parens",
"floating-point expressions are evaluated">,
NegFlag<SetFalse>>;

defm daz_ftz : SimpleMFlag<"daz-ftz",
"Globally set", "Do not globally set",
" the denormals-are-zero (DAZ) and flush-to-zero (FTZ) bits in the "
"floating-point control register on program startup">;

def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;

Expand Down Expand Up @@ -2888,7 +2893,7 @@ defm clangir : BoolFOption<"clangir",
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to compile">,
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Use the AST -> LLVM pipeline to compile">,
BothFlags<[], [ClangOption, CC1Option], "">>;
def emit_cir : Flag<["-"], "emit-cir">, Visibility<[ClangOption, CC1Option]>,
def emit_cir : Flag<["-"], "emit-cir">, Visibility<[CC1Option]>,
Group<Action_Group>, HelpText<"Build ASTs and then lower to ClangIR">;
/// ClangIR-specific options - END

Expand Down Expand Up @@ -4887,6 +4892,8 @@ def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group<m_wasm_Features_Group>;
def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group<m_wasm_Features_Group>;
def mhalf_precision : Flag<["-"], "mhalf-precision">, Group<m_wasm_Features_Group>;
def mno_half_precision : Flag<["-"], "mno-half-precision">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Frontend/ASTUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class ASTUnit {

/// A list of the serialization ID numbers for each of the top-level
/// declarations parsed within the precompiled preamble.
std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
std::vector<LocalDeclID> TopLevelDeclsInPreamble;

/// Whether we should be caching code-completion results.
bool ShouldCacheCodeCompletionResults : 1;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Frontend/MultiplexConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class MultiplexASTDeserializationListener : public ASTDeserializationListener {
void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
void TypeRead(serialization::TypeIdx Idx, QualType T) override;
void DeclRead(serialization::DeclID ID, const Decl *D) override;
void DeclRead(GlobalDeclID ID, const Decl *D) override;
void SelectorRead(serialization::SelectorID iD, Selector Sel) override;
void MacroDefinitionRead(serialization::PreprocessedEntityID,
MacroDefinitionRecord *MD) override;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {

/// Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
Decl *GetExternalDecl(Decl::DeclID ID) override;
Decl *GetExternalDecl(GlobalDeclID ID) override;

/// Complete the redeclaration chain if it's been extended since the
/// previous generation of the AST source.
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ class SemaOpenACC : public SemaBase {
/// conversions and diagnostics to 'int'.
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
SourceLocation Loc, Expr *IntExpr);

/// Checks and creates an Array Section used in an OpenACC construct/clause.
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
Expr *LowerBound,
SourceLocation ColonLocFirst, Expr *Length,
SourceLocation RBLoc);
};

} // namespace clang
Expand Down
186 changes: 8 additions & 178 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
#define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H

#include "clang/AST/DeclID.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
Expand Down Expand Up @@ -59,91 +60,9 @@ const unsigned VERSION_MINOR = 1;
/// and start at 1. 0 is reserved for NULL.
using IdentifierID = uint32_t;

/// 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.
///
/// FIXME: Merge with Decl::DeclID
using DeclID = uint32_t;

class LocalDeclID {
public:
explicit LocalDeclID(DeclID ID) : ID(ID) {}

DeclID get() const { return ID; }

private:
DeclID ID;
};

/// Wrapper class for DeclID. This is helpful to not mix the use of LocalDeclID
/// and GlobalDeclID to improve the type safety.
class GlobalDeclID {
public:
GlobalDeclID() : ID(0) {}
explicit GlobalDeclID(DeclID ID) : ID(ID) {}

DeclID get() const { return ID; }

explicit operator DeclID() const { return ID; }

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

private:
DeclID ID;
};

/// A helper iterator adaptor to convert the iterators to `SmallVector<DeclID>`
/// to the iterators to `SmallVector<GlobalDeclID>`.
class GlobalDeclIDIterator
: public llvm::iterator_adaptor_base<GlobalDeclIDIterator, const DeclID *,
std::forward_iterator_tag,
GlobalDeclID> {
public:
GlobalDeclIDIterator() : iterator_adaptor_base(nullptr) {}

GlobalDeclIDIterator(const DeclID *ID) : iterator_adaptor_base(ID) {}

value_type operator*() const { return GlobalDeclID(*I); }

bool operator==(const GlobalDeclIDIterator &RHS) const { return I == RHS.I; }
};

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

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

value_type operator*() const { return DeclID(*I); }

bool operator==(const DeclIDIterator &RHS) const { return I == RHS.I; }
};
/// An ID number that refers to a declaration in an AST file. See the comments
/// in DeclIDBase for details.
using DeclID = DeclIDBase::DeclID;

/// An ID number that refers to a type in an AST file.
///
Expand Down Expand Up @@ -1054,8 +973,8 @@ enum PredefinedTypeIDs {
/// OpenCL reserve_id type.
PREDEF_TYPE_RESERVE_ID_ID = 41,

/// The placeholder type for OpenMP array section.
PREDEF_TYPE_OMP_ARRAY_SECTION = 42,
/// The placeholder type for an array section.
PREDEF_TYPE_ARRAY_SECTION = 42,

/// The '__float128' type
PREDEF_TYPE_FLOAT128_ID = 43,
Expand Down Expand Up @@ -1238,74 +1157,6 @@ enum SpecialTypeIDs {
/// The number of special type IDs.
const unsigned NumSpecialTypeIDs = 8;

/// 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;

/// Record of updates for a declaration that was modified after
/// being deserialized. This can occur within DECLTYPES_BLOCK_ID.
const unsigned int DECL_UPDATES = 49;
Expand Down Expand Up @@ -2075,7 +1926,7 @@ enum StmtCode {
STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE,
STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE,
STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE,
EXPR_OMP_ARRAY_SECTION,
EXPR_ARRAY_SECTION,
EXPR_OMP_ARRAY_SHAPING,
EXPR_OMP_ITERATOR,

Expand Down Expand Up @@ -2132,7 +1983,7 @@ enum CleanupObjectKind { COK_Block, COK_CompoundLiteral };
/// Describes the categories of an Objective-C class.
struct ObjCCategoriesInfo {
// The ID of the definition
DeclID DefinitionID;
LocalDeclID DefinitionID;

// Offset into the array of category lists.
unsigned Offset;
Expand Down Expand Up @@ -2231,27 +2082,6 @@ template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> {
}
};

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

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 // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ASTDeserializationListener {
/// unqualified.
virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { }
/// A decl was deserialized from the AST file.
virtual void DeclRead(serialization::DeclID ID, const Decl *D) { }
virtual void DeclRead(GlobalDeclID ID, const Decl *D) {}
/// A selector was read from the AST file.
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {}
/// A macro definition was read from the AST file.
Expand Down
124 changes: 54 additions & 70 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,27 +501,23 @@ class ASTReader
/// = I + 1 has already been loaded.
llvm::PagedVector<Decl *> DeclsLoaded;

static_assert(std::is_same_v<serialization::DeclID, Decl::DeclID>);

using GlobalDeclMapType =
ContinuousRangeMap<serialization::GlobalDeclID, ModuleFile *, 4>;
using GlobalDeclMapType = ContinuousRangeMap<GlobalDeclID, ModuleFile *, 4>;

/// Mapping from global declaration IDs to the module in which the
/// declaration resides.
GlobalDeclMapType GlobalDeclMap;

using FileOffset = std::pair<ModuleFile *, uint64_t>;
using FileOffsetsTy = SmallVector<FileOffset, 2>;
using DeclUpdateOffsetsMap =
llvm::DenseMap<serialization::GlobalDeclID, FileOffsetsTy>;
using DeclUpdateOffsetsMap = llvm::DenseMap<GlobalDeclID, FileOffsetsTy>;

/// Declarations that have modifications residing in a later file
/// in the chain.
DeclUpdateOffsetsMap DeclUpdateOffsets;

using DelayedNamespaceOffsetMapTy = llvm::DenseMap<
serialization::GlobalDeclID,
std::pair</*LexicalOffset*/ uint64_t, /*VisibleOffset*/ uint64_t>>;
using DelayedNamespaceOffsetMapTy =
llvm::DenseMap<GlobalDeclID, std::pair</*LexicalOffset*/ uint64_t,
/*VisibleOffset*/ uint64_t>>;

/// Mapping from global declaration IDs to the lexical and visible block
/// offset for delayed namespace in reduced BMI.
Expand All @@ -535,13 +531,12 @@ class ASTReader

struct PendingUpdateRecord {
Decl *D;
serialization::GlobalDeclID ID;
GlobalDeclID ID;

// Whether the declaration was just deserialized.
bool JustLoaded;

PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D,
bool JustLoaded)
PendingUpdateRecord(GlobalDeclID ID, Decl *D, bool JustLoaded)
: D(D), ID(ID), JustLoaded(JustLoaded) {}
};

Expand Down Expand Up @@ -594,10 +589,10 @@ class ASTReader

struct FileDeclsInfo {
ModuleFile *Mod = nullptr;
ArrayRef<serialization::LocalDeclID> Decls;
ArrayRef<LocalDeclID> Decls;

FileDeclsInfo() = default;
FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
FileDeclsInfo(ModuleFile *Mod, ArrayRef<LocalDeclID> Decls)
: Mod(Mod), Decls(Decls) {}
};

Expand Down Expand Up @@ -635,8 +630,7 @@ class ASTReader

/// Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
llvm::DenseMap<serialization::GlobalDeclID, DeclContextVisibleUpdates>
PendingVisibleUpdates;
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;

/// The set of C++ or Objective-C classes that have forward
/// declarations that have not yet been linked to their definitions.
Expand All @@ -662,8 +656,7 @@ class ASTReader
/// Read the record that describes the visible contents of a DC.
bool ReadVisibleDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
uint64_t Offset,
serialization::GlobalDeclID ID);
uint64_t Offset, GlobalDeclID ID);

/// A vector containing identifiers that have already been
/// loaded.
Expand Down Expand Up @@ -816,22 +809,22 @@ class ASTReader
/// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
/// in the chain. The referenced declarations are deserialized and passed to
/// the consumer eagerly.
SmallVector<serialization::GlobalDeclID, 16> EagerlyDeserializedDecls;
SmallVector<GlobalDeclID, 16> EagerlyDeserializedDecls;

/// The IDs of all tentative definitions stored in the chain.
///
/// Sema keeps track of all tentative definitions in a TU because it has to
/// complete them and pass them on to CodeGen. Thus, tentative definitions in
/// the PCH chain must be eagerly deserialized.
SmallVector<serialization::GlobalDeclID, 16> TentativeDefinitions;
SmallVector<GlobalDeclID, 16> TentativeDefinitions;

/// The IDs of all CXXRecordDecls stored in the chain whose VTables are
/// used.
///
/// CodeGen has to emit VTables for these records, so they have to be eagerly
/// deserialized.
struct VTableUse {
serialization::GlobalDeclID ID;
GlobalDeclID ID;
SourceLocation::UIntTy RawLoc;
bool Used;
};
Expand All @@ -844,7 +837,7 @@ class ASTReader
/// instantiation where the first value is the ID of the decl and the second
/// is the instantiation location.
struct PendingInstantiation {
serialization::GlobalDeclID ID;
GlobalDeclID ID;
SourceLocation::UIntTy RawLoc;
};
SmallVector<PendingInstantiation, 64> PendingInstantiations;
Expand All @@ -857,11 +850,11 @@ class ASTReader

/// A snapshot of Sema's unused file-scoped variable tracking, for
/// generating warnings.
SmallVector<serialization::GlobalDeclID, 16> UnusedFileScopedDecls;
SmallVector<GlobalDeclID, 16> UnusedFileScopedDecls;

/// A list of all the delegating constructors we've seen, to diagnose
/// cycles.
SmallVector<serialization::GlobalDeclID, 4> DelegatingCtorDecls;
SmallVector<GlobalDeclID, 4> DelegatingCtorDecls;

/// Method selectors used in a @selector expression. Used for
/// implementation of -Wselector.
Expand All @@ -874,7 +867,7 @@ class ASTReader
/// The IDs of type aliases for ext_vectors that exist in the chain.
///
/// Used by Sema for finding sugared names for ext_vectors in diagnostics.
SmallVector<serialization::GlobalDeclID, 4> ExtVectorDecls;
SmallVector<GlobalDeclID, 4> ExtVectorDecls;

//@}

Expand All @@ -885,7 +878,7 @@ class ASTReader
/// The IDs of all potentially unused typedef names in the chain.
///
/// Sema tracks these to emit warnings.
SmallVector<serialization::GlobalDeclID, 16> UnusedLocalTypedefNameCandidates;
SmallVector<GlobalDeclID, 16> UnusedLocalTypedefNameCandidates;

/// Our current depth in #pragma cuda force_host_device begin/end
/// macros.
Expand All @@ -894,7 +887,7 @@ class ASTReader
/// The IDs of the declarations Sema stores directly.
///
/// Sema tracks a few important decls, such as namespace std, directly.
SmallVector<serialization::GlobalDeclID, 4> SemaDeclRefs;
SmallVector<GlobalDeclID, 4> SemaDeclRefs;

/// The IDs of the types ASTContext stores directly.
///
Expand All @@ -905,7 +898,7 @@ class ASTReader
///
/// The AST context tracks a few important decls, currently cudaConfigureCall,
/// directly.
SmallVector<serialization::GlobalDeclID, 2> CUDASpecialDeclRefs;
SmallVector<GlobalDeclID, 2> CUDASpecialDeclRefs;

/// The floating point pragma option settings.
SmallVector<uint64_t, 1> FPPragmaOptions;
Expand Down Expand Up @@ -954,12 +947,12 @@ class ASTReader
llvm::DenseMap<const Decl *, std::set<std::string>> OpenCLDeclExtMap;

/// A list of the namespaces we've seen.
SmallVector<serialization::GlobalDeclID, 4> KnownNamespaces;
SmallVector<GlobalDeclID, 4> KnownNamespaces;

/// A list of undefined decls with internal linkage followed by the
/// SourceLocation of a matching ODR-use.
struct UndefinedButUsedDecl {
serialization::GlobalDeclID ID;
GlobalDeclID ID;
SourceLocation::UIntTy RawLoc;
};
SmallVector<UndefinedButUsedDecl, 8> UndefinedButUsed;
Expand All @@ -974,8 +967,7 @@ class ASTReader
/// The IDs of all decls to be checked for deferred diags.
///
/// Sema tracks these to emit deferred diags.
llvm::SmallSetVector<serialization::GlobalDeclID, 4>
DeclsToCheckForDeferredDiags;
llvm::SmallSetVector<GlobalDeclID, 4> DeclsToCheckForDeferredDiags;

private:
struct ImportedSubmodule {
Expand Down Expand Up @@ -1112,7 +1104,7 @@ class ASTReader
///
/// The declarations on the identifier chain for these identifiers will be
/// loaded once the recursive loading has completed.
llvm::MapVector<IdentifierInfo *, SmallVector<serialization::GlobalDeclID, 4>>
llvm::MapVector<IdentifierInfo *, SmallVector<GlobalDeclID, 4>>
PendingIdentifierInfos;

/// The set of lookup results that we have faked in order to support
Expand Down Expand Up @@ -1157,8 +1149,8 @@ class ASTReader
/// been loaded but its DeclContext was not set yet.
struct PendingDeclContextInfo {
Decl *D;
serialization::GlobalDeclID SemaDC;
serialization::GlobalDeclID LexicalDC;
GlobalDeclID SemaDC;
GlobalDeclID LexicalDC;
};

/// The set of Decls that have been loaded but their DeclContexts are
Expand Down Expand Up @@ -1239,8 +1231,7 @@ class ASTReader
/// module is loaded.
SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;

using KeyDeclsMap =
llvm::DenseMap<Decl *, SmallVector<serialization::GlobalDeclID, 2>>;
using KeyDeclsMap = llvm::DenseMap<Decl *, SmallVector<GlobalDeclID, 2>>;

/// A mapping from canonical declarations to the set of global
/// declaration IDs for key declaration that have been merged with that
Expand Down Expand Up @@ -1449,19 +1440,18 @@ class ASTReader
QualType readTypeRecord(unsigned Index);
RecordLocation TypeCursorForIndex(unsigned Index);
void LoadedDecl(unsigned Index, Decl *D);
Decl *ReadDeclRecord(serialization::GlobalDeclID ID);
Decl *ReadDeclRecord(GlobalDeclID ID);
void markIncompleteDeclChain(Decl *D);

/// Returns the most recent declaration of a declaration (which must be
/// of a redeclarable kind) that is either local or has already been loaded
/// merged into its redecl chain.
Decl *getMostRecentExistingDecl(Decl *D);

RecordLocation DeclCursorForID(serialization::GlobalDeclID ID,
SourceLocation &Location);
RecordLocation DeclCursorForID(GlobalDeclID ID, SourceLocation &Location);
void loadDeclUpdateRecords(PendingUpdateRecord &Record);
void loadPendingDeclChain(Decl *D, uint64_t LocalOffset);
void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D,
void loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D,
unsigned PreviousGeneration = 0);

RecordLocation getLocalBitOffset(uint64_t GlobalOffset);
Expand Down Expand Up @@ -1496,19 +1486,18 @@ class ASTReader
unsigned ClientLoadCapabilities);

public:
class ModuleDeclIterator
: public llvm::iterator_adaptor_base<
ModuleDeclIterator, const serialization::LocalDeclID *,
std::random_access_iterator_tag, const Decl *, ptrdiff_t,
const Decl *, const Decl *> {
class ModuleDeclIterator : public llvm::iterator_adaptor_base<
ModuleDeclIterator, const LocalDeclID *,
std::random_access_iterator_tag, const Decl *,
ptrdiff_t, const Decl *, const Decl *> {
ASTReader *Reader = nullptr;
ModuleFile *Mod = nullptr;

public:
ModuleDeclIterator() : iterator_adaptor_base(nullptr) {}

ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
const serialization::LocalDeclID *Pos)
const LocalDeclID *Pos)
: iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {}

value_type operator*() const {
Expand Down Expand Up @@ -1536,9 +1525,8 @@ class ASTReader

void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);

void addPendingDeclContextInfo(Decl *D,
serialization::GlobalDeclID SemaDC,
serialization::GlobalDeclID LexicalDC) {
void addPendingDeclContextInfo(Decl *D, GlobalDeclID SemaDC,
GlobalDeclID LexicalDC) {
assert(D);
PendingDeclContextInfo Info = { D, SemaDC, LexicalDC };
PendingDeclContextInfos.push_back(Info);
Expand Down Expand Up @@ -1916,38 +1904,36 @@ class ASTReader

/// Map from a local declaration ID within a given module to a
/// global declaration ID.
serialization::GlobalDeclID
getGlobalDeclID(ModuleFile &F, serialization::LocalDeclID LocalID) const;
GlobalDeclID getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const;

/// Returns true if global DeclID \p ID originated from module \p M.
bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const;
bool isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const;

/// Retrieve the module file that owns the given declaration, or NULL
/// if the declaration is not from a module file.
ModuleFile *getOwningModuleFile(const Decl *D);

/// Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
SourceLocation getSourceLocationForDeclID(GlobalDeclID ID);

/// Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
Decl *GetDecl(serialization::GlobalDeclID ID);
Decl *GetExternalDecl(Decl::DeclID ID) override;
Decl *GetDecl(GlobalDeclID ID);
Decl *GetExternalDecl(GlobalDeclID ID) override;

/// Resolve a declaration ID into a declaration. Return 0 if it's not
/// been loaded yet.
Decl *GetExistingDecl(serialization::GlobalDeclID ID);
Decl *GetExistingDecl(GlobalDeclID ID);

/// Reads a declaration with the given local ID in the given module.
Decl *GetLocalDecl(ModuleFile &F, serialization::LocalDeclID LocalID) {
Decl *GetLocalDecl(ModuleFile &F, LocalDeclID LocalID) {
return GetDecl(getGlobalDeclID(F, LocalID));
}

/// Reads a declaration with the given local ID in the given module.
///
/// \returns The requested declaration, casted to the given return type.
template <typename T>
T *GetLocalDeclAs(ModuleFile &F, serialization::LocalDeclID LocalID) {
template <typename T> T *GetLocalDeclAs(ModuleFile &F, LocalDeclID LocalID) {
return cast_or_null<T>(GetLocalDecl(F, LocalID));
}

Expand All @@ -1956,16 +1942,15 @@ class ASTReader
///
/// \returns the global ID of the given declaration as known in the given
/// module file.
serialization::DeclID
mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
serialization::GlobalDeclID GlobalID);
LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
GlobalDeclID GlobalID);

/// Reads a declaration ID from the given position in a record in the
/// given module.
///
/// \returns The declaration ID read from the record, adjusted to a global ID.
serialization::GlobalDeclID
ReadDeclID(ModuleFile &F, const RecordData &Record, unsigned &Idx);
GlobalDeclID ReadDeclID(ModuleFile &F, const RecordData &Record,
unsigned &Idx);

/// Reads a declaration from the given position in a record in the
/// given module.
Expand Down Expand Up @@ -2139,10 +2124,9 @@ class ASTReader
void LoadSelector(Selector Sel);

void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
void SetGloballyVisibleDecls(
IdentifierInfo *II,
const SmallVectorImpl<serialization::GlobalDeclID> &DeclIDs,
SmallVectorImpl<Decl *> *Decls = nullptr);
void SetGloballyVisibleDecls(IdentifierInfo *II,
const SmallVectorImpl<GlobalDeclID> &DeclIDs,
SmallVectorImpl<Decl *> *Decls = nullptr);

/// Report a diagnostic.
DiagnosticBuilder Diag(unsigned DiagID) const;
Expand Down Expand Up @@ -2383,7 +2367,7 @@ class ASTReader

// Contains the IDs for declarations that were requested before we have
// access to a Sema object.
SmallVector<serialization::GlobalDeclID, 16> PreloadedDeclIDs;
SmallVector<GlobalDeclID, 16> PreloadedDeclIDs;

/// Retrieve the semantic analysis object used to analyze the
/// translation unit in which the precompiled header is being
Expand Down
6 changes: 2 additions & 4 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class ASTRecordReader
/// Reads a declaration with the given local ID in the given module.
///
/// \returns The requested declaration, casted to the given return type.
template <typename T> T *GetLocalDeclAs(serialization::LocalDeclID LocalID) {
template <typename T> T *GetLocalDeclAs(LocalDeclID LocalID) {
return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
}

Expand Down Expand Up @@ -182,9 +182,7 @@ class ASTRecordReader
/// Reads a declaration ID from the given position in this record.
///
/// \returns The declaration ID read from the record, adjusted to a global ID.
serialization::GlobalDeclID readDeclID() {
return Reader->ReadDeclID(*F, Record, Idx);
}
GlobalDeclID readDeclID() { return Reader->ReadDeclID(*F, Record, Idx); }

/// Reads a declaration from the given position in a record in the
/// given module, advancing Idx.
Expand Down
28 changes: 14 additions & 14 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,18 @@ class ASTWriter : public ASTDeserializationListener,
llvm::SmallVector<NamespaceDecl *, 16> DelayedNamespace;

/// The first ID number we can use for our own declarations.
serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS;
LocalDeclID FirstDeclID = LocalDeclID(clang::NUM_PREDEF_DECL_IDS);

/// The decl ID that will be assigned to the next new decl.
serialization::DeclID NextDeclID = FirstDeclID;
LocalDeclID NextDeclID = FirstDeclID;

/// Map that provides the ID numbers of each declaration within
/// the output stream, as well as those deserialized from a chained PCH.
///
/// The ID numbers of declarations are consecutive (in order of
/// discovery) and start at 2. 1 is reserved for the translation
/// unit, while 0 is reserved for NULL.
llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs;
llvm::DenseMap<const Decl *, LocalDeclID> DeclIDs;

/// Offset of each declaration in the bitstream, indexed by
/// the declaration's ID.
Expand All @@ -233,9 +233,8 @@ class ASTWriter : public ASTDeserializationListener,
/// are relative to this value.
uint64_t DeclTypesBlockStartOffset = 0;

/// Sorted (by file offset) vector of pairs of file offset/DeclID.
using LocDeclIDsTy =
SmallVector<std::pair<unsigned, serialization::DeclID>, 64>;
/// Sorted (by file offset) vector of pairs of file offset/LocalDeclID.
using LocDeclIDsTy = SmallVector<std::pair<unsigned, LocalDeclID>, 64>;
struct DeclIDInFileInfo {
LocDeclIDsTy DeclIDs;

Expand All @@ -250,7 +249,7 @@ class ASTWriter : public ASTDeserializationListener,
/// that it contains.
FileDeclIDsTy FileDeclIDs;

void associateDeclWithFile(const Decl *D, serialization::DeclID);
void associateDeclWithFile(const Decl *D, LocalDeclID);

/// The first ID number we can use for our own types.
serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS;
Expand Down Expand Up @@ -421,8 +420,8 @@ class ASTWriter : public ASTDeserializationListener,
/// headers. The declarations themselves are stored as declaration
/// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
/// record.
SmallVector<serialization::DeclID, 16> EagerlyDeserializedDecls;
SmallVector<serialization::DeclID, 16> ModularCodegenDecls;
RecordData EagerlyDeserializedDecls;
RecordData ModularCodegenDecls;

/// DeclContexts that have received extensions since their serialized
/// form.
Expand Down Expand Up @@ -709,20 +708,21 @@ class ASTWriter : public ASTDeserializationListener,
return false;
auto I = DeclIDs.find(D);
return (I == DeclIDs.end() ||
I->second >= serialization::NUM_PREDEF_DECL_IDS);
I->second.get() >= clang::NUM_PREDEF_DECL_IDS);
};

/// Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordDataImpl &Record);
// Emit a reference to a declaration if the declaration was emitted.
void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record);

/// Force a declaration to be emitted and get its ID.
serialization::DeclID GetDeclRef(const Decl *D);
/// Force a declaration to be emitted and get its local ID to the module file
/// been writing.
LocalDeclID GetDeclRef(const Decl *D);

/// Determine the declaration ID of an already-emitted
/// Determine the local declaration ID of an already-emitted
/// declaration.
serialization::DeclID getDeclID(const Decl *D);
LocalDeclID getDeclID(const Decl *D);

/// Whether or not the declaration got emitted. If not, it wouldn't be
/// emitted.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ class ModuleFile {
llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;

/// Array of file-level DeclIDs sorted by file.
const serialization::LocalDeclID *FileSortedDecls = nullptr;
const LocalDeclID *FileSortedDecls = nullptr;
unsigned NumFileSortedDecls = 0;

/// Array of category list location information within this
Expand Down
14 changes: 5 additions & 9 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,11 @@ class StoreManager {
/// invalidated. This should include any regions explicitly invalidated
/// even if they do not currently have bindings. Pass \c NULL if this
/// information will not be used.
virtual StoreRef invalidateRegions(Store store,
ArrayRef<SVal> Values,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
const CallEvent *Call,
InvalidatedSymbols &IS,
RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *InvalidatedTopLevel,
InvalidatedRegions *Invalidated) = 0;
virtual StoreRef invalidateRegions(
Store store, ArrayRef<SVal> Values, const Expr *Ex, unsigned Count,
const LocationContext *LCtx, const CallEvent *Call,
InvalidatedSymbols &IS, RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) = 0;

/// enterStackFrame - Let the StoreManager to do something when execution
/// engine is about to execute into a callee.
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 25; // SwiftImportAs
const uint16_t VERSION_MINOR = 26; // SwiftCopyable

const uint8_t kSwiftCopyable = 1;
const uint8_t kSwiftNonCopyable = 2;

using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
using IdentifierIDField = llvm::BCVBR<16>;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,13 @@ class TagTableInfo
Info.EnumExtensibility =
static_cast<EnumExtensibilityKind>((Payload & 0x3) - 1);

uint8_t Copyable =
endian::readNext<uint8_t, llvm::endianness::little>(Data);
if (Copyable == kSwiftNonCopyable)
Info.setSwiftCopyable(std::optional(false));
else if (Copyable == kSwiftCopyable)
Info.setSwiftCopyable(std::optional(true));

unsigned ImportAsLength =
endian::readNext<uint16_t, llvm::endianness::little>(Data);
if (ImportAsLength > 0) {
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/APINotes/APINotesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
1 + getCommonTypeInfoSize(TI);
2 + getCommonTypeInfoSize(TI);
}

void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) {
Expand All @@ -1146,6 +1146,11 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {

writer.write<uint8_t>(Flags);

if (auto Copyable = TI.isSwiftCopyable())
writer.write<uint8_t>(*Copyable ? kSwiftCopyable : kSwiftNonCopyable);
else
writer.write<uint8_t>(0);

if (auto ImportAs = TI.SwiftImportAs) {
writer.write<uint16_t>(ImportAs->size() + 1);
OS.write(ImportAs->c_str(), ImportAs->size());
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/APINotes/APINotesYAMLCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ struct Tag {
std::optional<EnumExtensibilityKind> EnumExtensibility;
std::optional<bool> FlagEnum;
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
std::optional<bool> SwiftCopyable;
};

typedef std::vector<Tag> TagsSeq;
Expand Down Expand Up @@ -452,6 +453,7 @@ template <> struct MappingTraits<Tag> {
IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
IO.mapOptional("FlagEnum", T.FlagEnum);
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
}
};
} // namespace yaml
Expand Down Expand Up @@ -1009,6 +1011,9 @@ class YAMLConverter {
if (Tag.SwiftReleaseOp)
TI.SwiftReleaseOp = Tag.SwiftReleaseOp;

if (Tag.SwiftCopyable)
TI.setSwiftCopyable(Tag.SwiftCopyable);

if (Tag.EnumConvenienceKind) {
if (Tag.EnumExtensibility) {
emitError(
Expand Down
14 changes: 6 additions & 8 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ void ASTContext::addModuleInitializer(Module *M, Decl *D) {
}

void ASTContext::addLazyModuleInitializers(Module *M,
ArrayRef<Decl::DeclID> IDs) {
ArrayRef<GlobalDeclID> IDs) {
auto *&Inits = ModuleInitializers[M];
if (!Inits)
Inits = new (*this) PerModuleInitializers;
Expand Down Expand Up @@ -1321,16 +1321,14 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,

// Placeholder type for OMP array sections.
if (LangOpts.OpenMP) {
InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
InitBuiltinType(ArraySectionTy, BuiltinType::ArraySection);
InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping);
InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator);
}
// Placeholder type for OpenACC array sections.
if (LangOpts.OpenACC) {
// FIXME: Once we implement OpenACC array sections in Sema, this will either
// be combined with the OpenMP type, or given its own type. In the meantime,
// just use the OpenMP type so that parsing can work.
InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
// Placeholder type for OpenACC array sections, if we are ALSO in OMP mode,
// don't bother, as we're just using the same type as OMP.
if (LangOpts.OpenACC && !LangOpts.OpenMP) {
InitBuiltinType(ArraySectionTy, BuiltinType::ArraySection);
}
if (LangOpts.MatrixTypes)
InitBuiltinType(IncompleteMatrixIdxTy, BuiltinType::IncompleteMatrixIdx);
Expand Down
Loading