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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

SourceRange getSourceRange() const override LLVM_READONLY;

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

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

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

SourceRange getSourceRange() const override LLVM_READONLY;

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

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

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

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

SourceRange getSourceRange() const override LLVM_READONLY;

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

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

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

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

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

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

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

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

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

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

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

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

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

/// If this friend declaration names an (untemplated but possibly
Expand Down
227 changes: 227 additions & 0 deletions clang/include/clang/AST/DeclID.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
//===--- DeclID.h - ID number for deserialized declarations ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines DeclID class family to describe the deserialized
// declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to
// `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to
// require the use of `DeclID` to explicit.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_DECLID_H
#define LLVM_CLANG_AST_DECLID_H

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

namespace clang {

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

/// The translation unit.
PREDEF_DECL_TRANSLATION_UNIT_ID = 1,

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

explicit operator DeclID() const { return ID; }

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

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

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

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

protected:
DeclID ID;
};

class LocalDeclID : public DeclIDBase {
using Base = DeclIDBase;

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

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

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

class GlobalDeclID : public DeclIDBase {
using Base = DeclIDBase;

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

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

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

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

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

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

} // namespace clang

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

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

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

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

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

} // namespace llvm

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

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

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

SourceRange getSourceRange() const override LLVM_READONLY;

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

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

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

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

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

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

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

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

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

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

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

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

ObjCCategoryDecl *getCategoryDecl() const;

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

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

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

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

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

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

SourceRange getSourceRange() const override LLVM_READONLY;

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

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

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

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

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

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

SourceRange getSourceRange() const override LLVM_READONLY;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

};

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

public:
enum ArraySectionType { OMPArraySection, OpenACCArraySection };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/// Frontend produces RecoveryExprs on semantic errors that prevent creating
/// other well-formed expressions. E.g. when type-checking of a binary operator
/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose
Expand Down
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;
}
12 changes: 5 additions & 7 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3755,14 +3755,12 @@ def err_sme_definition_using_za_in_non_sme_target : Error<
def err_sme_definition_using_zt0_in_non_sme2_target : Error<
"function using ZT0 state requires 'sme2'">;
def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
"passing a VL-dependent argument to/from a function that has a different"
" streaming-mode. The streaming and non-streaming vector lengths may be"
" different">,
"%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different"
" streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
"passing/returning a VL-dependent argument to/from a __arm_locally_streaming"
" function. The streaming and non-streaming vector"
" lengths may be different">,
"%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a locally streaming function is undefined"
" behaviour when the streaming and non-streaming vector lengths are different at runtime">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
Expand Down Expand Up @@ -11163,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
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
97 changes: 74 additions & 23 deletions clang/include/clang/Basic/riscv_vector.td

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions clang/include/clang/CIR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include ) # --includedir
set(MLIR_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/mlir/include)
include_directories(${MLIR_INCLUDE_DIR})
include_directories(${MLIR_TABLEGEN_OUTPUT_DIR})

add_subdirectory(Dialect)
1 change: 1 addition & 0 deletions clang/include/clang/CIR/Dialect/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(IR)
16 changes: 16 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRDialect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//===- CIRDialect.h - CIR dialect -------------------------------*- 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 declares the CIR dialect.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H
#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H

#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H
44 changes: 44 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRDialect.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===- CIRDialect.td - CIR dialect -------------------------*- tablegen -*-===//
//
// 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 declares the CIR dialect.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT
#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT

include "mlir/IR/OpBase.td"

def CIR_Dialect : Dialect {
let name = "cir";

// A short one-line summary of our dialect.
let summary = "A high-level dialect for analyzing and optimizing Clang "
"supported languages";

let cppNamespace = "::mlir::cir";

let useDefaultAttributePrinterParser = 0;
let useDefaultTypePrinterParser = 0;

let extraClassDeclaration = [{
void registerAttributes();
void registerTypes();

Type parseType(DialectAsmParser &parser) const override;
void printType(Type type, DialectAsmPrinter &printer) const override;

Attribute parseAttribute(DialectAsmParser &parser,
Type type) const override;

void printAttribute(Attribute attr, DialectAsmPrinter &os) const override;
}];
}

#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT
19 changes: 19 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- CIROps.td - CIR dialect definition -----------------*- tablegen -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Definition of the CIR dialect
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIROPS
#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS

include "clang/CIR/Dialect/IR/CIRDialect.td"

#endif // LLVM_CLANG_CIR_DIALECT_IR_CIROPS
16 changes: 16 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This replicates part of the add_mlir_dialect cmake function from MLIR that
# cannot be used here. This happens because it expects to be run inside MLIR
# directory which is not the case for CIR (and also FIR, both have similar
# workarounds).

# Equivalent to add_mlir_dialect(CIROps cir)
set(LLVM_TARGET_DEFINITIONS CIROps.td)
mlir_tablegen(CIROps.h.inc -gen-op-decls)
mlir_tablegen(CIROps.cpp.inc -gen-op-defs)
mlir_tablegen(CIROpsTypes.h.inc -gen-typedef-decls)
mlir_tablegen(CIROpsTypes.cpp.inc -gen-typedef-defs)
mlir_tablegen(CIROpsDialect.h.inc -gen-dialect-decls)
mlir_tablegen(CIROpsDialect.cpp.inc -gen-dialect-defs)
add_public_tablegen_target(MLIRCIROpsIncGen)
add_dependencies(mlir-headers MLIRCIROpsIncGen)

21 changes: 17 additions & 4 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ class MarshallingInfoVisibility<KeyPathAndMacro kpm, code default>
// Key paths that are constant during parsing of options with the same key path prefix.
defvar cplusplus = LangOpts<"CPlusPlus">;
defvar cpp11 = LangOpts<"CPlusPlus11">;
defvar cpp14 = LangOpts<"CPlusPlus14">;
defvar cpp17 = LangOpts<"CPlusPlus17">;
defvar cpp20 = LangOpts<"CPlusPlus20">;
defvar c99 = LangOpts<"C99">;
Expand Down Expand Up @@ -2615,6 +2616,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 @@ -3365,10 +3371,9 @@ defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-arg
"Enable C++17 relaxed template template argument matching">,
NegFlag<SetFalse>>;
defm sized_deallocation : BoolFOption<"sized-deallocation",
LangOpts<"SizedDeallocation">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Enable C++14 sized global deallocation functions">,
NegFlag<SetFalse>>;
LangOpts<"SizedDeallocation">, Default<cpp14.KeyPath>,
PosFlag<SetTrue, [], [], "Enable C++14 sized global deallocation functions">,
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
defm aligned_allocation : BoolFOption<"aligned-allocation",
LangOpts<"AlignedAllocation">, Default<cpp17.KeyPath>,
PosFlag<SetTrue, [], [ClangOption], "Enable C++17 aligned allocation functions">,
Expand Down Expand Up @@ -5508,6 +5513,14 @@ def fno_rtlib_add_rpath: Flag<["-"], "fno-rtlib-add-rpath">,
Visibility<[ClangOption, FlangOption]>,
HelpText<"Do not add -rpath with architecture-specific resource directory to the linker flags. "
"When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags">;
def frtlib_defaultlib : Flag<["-"], "frtlib-defaultlib">,
Visibility<[ClangOption, CLOption]>,
Group<f_Group>,
HelpText<"On Windows, emit /defaultlib: directives to link compiler-rt libraries (default)">;
def fno_rtlib_defaultlib : Flag<["-"], "fno-rtlib-defaultlib">,
Visibility<[ClangOption, CLOption]>,
Group<f_Group>,
HelpText<"On Windows, do not emit /defaultlib: directives to link compiler-rt libraries">;
def offload_add_rpath: Flag<["--"], "offload-add-rpath">,
Flags<[NoArgumentUnused]>,
Alias<frtlib_add_rpath>;
Expand Down
135 changes: 91 additions & 44 deletions clang/include/clang/ExtractAPI/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,20 @@ struct APIRecord {
RK_ClassTemplate,
RK_ClassTemplateSpecialization,
RK_ClassTemplatePartialSpecialization,
RK_LastRecordContext,
RK_GlobalFunction,
RK_GlobalFunctionTemplate,
RK_GlobalFunctionTemplateSpecialization,
RK_StructField,
RK_UnionField,
RK_CXXField,
RK_StaticField,
RK_CXXFieldTemplate,
RK_GlobalVariable,
RK_GlobalVariableTemplate,
RK_GlobalVariableTemplateSpecialization,
RK_GlobalVariableTemplatePartialSpecialization,
RK_LastRecordContext,
RK_GlobalFunction,
RK_GlobalFunctionTemplate,
RK_GlobalFunctionTemplateSpecialization,
RK_EnumConstant,
RK_StructField,
RK_UnionField,
RK_StaticField,
RK_CXXField,
RK_CXXFieldTemplate,
RK_Concept,
RK_CXXStaticMethod,
RK_CXXInstanceMethod,
Expand Down Expand Up @@ -321,6 +321,10 @@ class RecordContext {

RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}

/// Append \p Other children chain into ours and empty out Other's record
/// chain.
void stealRecordChain(RecordContext &Other);

APIRecord::RecordKind getKind() const { return Kind; }

struct record_iterator {
Expand Down Expand Up @@ -370,6 +374,7 @@ class RecordContext {
APIRecord::RecordKind Kind;
mutable APIRecord *First = nullptr;
mutable APIRecord *Last = nullptr;
bool IsWellFormed() const;

protected:
friend class APISet;
Expand Down Expand Up @@ -475,31 +480,36 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
};

/// This holds information associated with global functions.
struct GlobalVariableRecord : APIRecord {
struct GlobalVariableRecord : APIRecord, RecordContext {
GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
LinkageInfo Linkage, const DocComment &Comment,
DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
: APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
std::move(Availability), Linkage, Comment, Declaration,
SubHeading, IsFromSystemHeader) {}
SubHeading, IsFromSystemHeader),
RecordContext(RK_GlobalVariable) {}

GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
SymbolReference Parent,

PresumedLoc Loc, AvailabilityInfo Availability,
LinkageInfo Linkage, const DocComment &Comment,
SymbolReference Parent, PresumedLoc Loc,
AvailabilityInfo Availability, LinkageInfo Linkage,
const DocComment &Comment,
DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
Linkage, Comment, Declaration, SubHeading,
IsFromSystemHeader) {}
IsFromSystemHeader),
RecordContext(Kind) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
}
static bool classofKind(RecordKind K) { return K == RK_GlobalVariable; }
static bool classofKind(RecordKind K) {
return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate ||
K == RK_GlobalVariableTemplateSpecialization ||
K == RK_GlobalVariableTemplatePartialSpecialization;
}

private:
virtual void anchor();
Expand Down Expand Up @@ -591,36 +601,64 @@ struct EnumConstantRecord : APIRecord {
virtual void anchor();
};

struct TagRecord : APIRecord, RecordContext {
TagRecord(RecordKind Kind, StringRef USR, StringRef Name,
SymbolReference Parent, PresumedLoc Loc,
AvailabilityInfo Availability, const DocComment &Comment,
DeclarationFragments Declaration, DeclarationFragments SubHeading,
bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator,
AccessControl Access = AccessControl())
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader, std::move(Access)),
RecordContext(Kind),
IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){};

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
}
static bool classofKind(RecordKind K) {
return K == RK_Struct || K == RK_Union || K == RK_Enum;
}

bool IsEmbeddedInVarDeclarator;

virtual ~TagRecord() = 0;
};

/// This holds information associated with enums.
struct EnumRecord : APIRecord, RecordContext {
struct EnumRecord : TagRecord {
EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
const DocComment &Comment, DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
: APIRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader),
RecordContext(RK_Enum) {}
DeclarationFragments SubHeading, bool IsFromSystemHeader,
bool IsEmbeddedInVarDeclarator,
AccessControl Access = AccessControl())
: TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
Comment, Declaration, SubHeading, IsFromSystemHeader,
IsEmbeddedInVarDeclarator, std::move(Access)) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
}

static bool classofKind(RecordKind K) { return K == RK_Enum; }

private:
virtual void anchor();
};

/// This holds information associated with struct or union fields fields.
struct RecordFieldRecord : APIRecord {
struct RecordFieldRecord : APIRecord, RecordContext {
RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
SymbolReference Parent, PresumedLoc Loc,
AvailabilityInfo Availability, const DocComment &Comment,
DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader) {}
IsFromSystemHeader),
RecordContext(Kind) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
Expand All @@ -633,16 +671,17 @@ struct RecordFieldRecord : APIRecord {
};

/// This holds information associated with structs and unions.
struct RecordRecord : APIRecord, RecordContext {
struct RecordRecord : TagRecord {
RecordRecord(RecordKind Kind, StringRef USR, StringRef Name,
SymbolReference Parent, PresumedLoc Loc,
AvailabilityInfo Availability, const DocComment &Comment,
DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader),
RecordContext(Kind) {}
DeclarationFragments SubHeading, bool IsFromSystemHeader,
bool IsEmbeddedInVarDeclarator,
AccessControl Access = AccessControl())
: TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
Comment, Declaration, SubHeading, IsFromSystemHeader,
IsEmbeddedInVarDeclarator, std::move(Access)) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
Expand All @@ -651,6 +690,8 @@ struct RecordRecord : APIRecord, RecordContext {
return K == RK_Struct || K == RK_Union;
}

bool isAnonymousWithNoTypedef() { return Name.empty(); }

virtual ~RecordRecord() = 0;
};

Expand All @@ -676,9 +717,11 @@ struct StructRecord : RecordRecord {
StructRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
const DocComment &Comment, DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
DeclarationFragments SubHeading, bool IsFromSystemHeader,
bool IsEmbeddedInVarDeclarator)
: RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability),
Comment, Declaration, SubHeading, IsFromSystemHeader) {}
Comment, Declaration, SubHeading, IsFromSystemHeader,
IsEmbeddedInVarDeclarator) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
Expand Down Expand Up @@ -711,9 +754,11 @@ struct UnionRecord : RecordRecord {
UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
const DocComment &Comment, DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool IsFromSystemHeader)
DeclarationFragments SubHeading, bool IsFromSystemHeader,
bool IsEmbeddedInVarDeclarator)
: RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability),
Comment, Declaration, SubHeading, IsFromSystemHeader) {}
Comment, Declaration, SubHeading, IsFromSystemHeader,
IsEmbeddedInVarDeclarator) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
Expand All @@ -724,15 +769,16 @@ struct UnionRecord : RecordRecord {
virtual void anchor();
};

struct CXXFieldRecord : APIRecord {
struct CXXFieldRecord : APIRecord, RecordContext {
CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
const DocComment &Comment, DeclarationFragments Declaration,
DeclarationFragments SubHeading, AccessControl Access,
bool IsFromSystemHeader)
: APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader, std::move(Access)) {}
IsFromSystemHeader, std::move(Access)),
RecordContext(RK_CXXField) {}

CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
SymbolReference Parent, PresumedLoc Loc,
Expand All @@ -742,7 +788,8 @@ struct CXXFieldRecord : APIRecord {
bool IsFromSystemHeader)
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader, std::move(Access)) {}
IsFromSystemHeader, std::move(Access)),
RecordContext(Kind) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
Expand Down Expand Up @@ -1118,18 +1165,18 @@ struct ObjCContainerRecord : APIRecord, RecordContext {
virtual ~ObjCContainerRecord() = 0;
};

struct CXXClassRecord : APIRecord, RecordContext {
struct CXXClassRecord : RecordRecord {
SmallVector<SymbolReference> Bases;

CXXClassRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
const DocComment &Comment, DeclarationFragments Declaration,
DeclarationFragments SubHeading, RecordKind Kind,
AccessControl Access, bool IsFromSystemHeader)
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
LinkageInfo::none(), Comment, Declaration, SubHeading,
IsFromSystemHeader, std::move(Access)),
RecordContext(Kind) {}
AccessControl Access, bool IsFromSystemHeader,
bool IsEmbeddedInVarDeclarator = false)
: RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
Comment, Declaration, SubHeading, IsFromSystemHeader,
IsEmbeddedInVarDeclarator, std::move(Access)) {}

static bool classof(const APIRecord *Record) {
return classofKind(Record->getKind());
Expand Down
16 changes: 14 additions & 2 deletions clang/include/clang/ExtractAPI/APIRecords.inc
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ CONCRETE_RECORD(GlobalVariableTemplateSpecializationRecord,
CONCRETE_RECORD(GlobalVariableTemplatePartialSpecializationRecord,
GlobalVariableRecord,
RK_GlobalVariableTemplatePartialSpecialization)
ABSTRACT_RECORD(TagRecord, APIRecord)
CONCRETE_RECORD(EnumConstantRecord, APIRecord, RK_EnumConstant)
CONCRETE_RECORD(EnumRecord, APIRecord, RK_Enum)
CONCRETE_RECORD(EnumRecord, TagRecord, RK_Enum)
ABSTRACT_RECORD(RecordFieldRecord, APIRecord)
ABSTRACT_RECORD(RecordRecord, APIRecord)
ABSTRACT_RECORD(RecordRecord, TagRecord)
CONCRETE_RECORD(StructFieldRecord, RecordFieldRecord, RK_StructField)
CONCRETE_RECORD(StructRecord, APIRecord, RK_Struct)
CONCRETE_RECORD(UnionFieldRecord, RecordFieldRecord, RK_UnionField)
Expand Down Expand Up @@ -99,5 +100,16 @@ RECORD_CONTEXT(ClassTemplateSpecializationRecord,
RK_ClassTemplateSpecialization)
RECORD_CONTEXT(ClassTemplatePartialSpecializationRecord,
RK_ClassTemplatePartialSpecialization)
RECORD_CONTEXT(StructFieldRecord, RK_StructField)
RECORD_CONTEXT(UnionFieldRecord, RK_UnionField)
RECORD_CONTEXT(CXXFieldRecord, RK_CXXField)
RECORD_CONTEXT(StaticFieldRecord, RK_StaticField)
RECORD_CONTEXT(CXXFieldTemplateRecord, RK_CXXFieldTemplate)
RECORD_CONTEXT(GlobalVariableRecord, RK_GlobalVariable)
RECORD_CONTEXT(GlobalVariableTemplateRecord, RK_GlobalVariableTemplate)
RECORD_CONTEXT(GlobalVariableTemplateSpecializationRecord,
RK_GlobalVariableTemplateSpecialization)
RECORD_CONTEXT(GlobalVariableTemplatePartialSpecializationRecord,
RK_GlobalVariableTemplatePartialSpecialization)

#undef RECORD_CONTEXT
Loading