37 changes: 31 additions & 6 deletions clang/include/clang/AST/DeclAccessPair.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "clang/Basic/Specifiers.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Endian.h"

namespace clang {

Expand All @@ -27,9 +28,17 @@ class NamedDecl;
/// A POD class for pairing a NamedDecl* with an access specifier.
/// Can be put into unions.
class DeclAccessPair {
uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
/// Use the lower 2 bit to store AccessSpecifier. Use the higher
/// 61 bit to store the pointer to a NamedDecl or the DeclID to
/// a NamedDecl. If the 3rd bit is set, storing the DeclID, otherwise
/// storing the pointer.
llvm::support::detail::packed_endian_specific_integral<
uint64_t, llvm::endianness::native, alignof(void *)>
Ptr;

enum { Mask = 0x3 };
enum { ASMask = 0x3, Mask = 0x7 };

bool isDeclID() const { return (Ptr >> 2) & 0x1; }

public:
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
Expand All @@ -38,12 +47,22 @@ class DeclAccessPair {
return p;
}

static DeclAccessPair makeLazy(uint64_t ID, AccessSpecifier AS) {
DeclAccessPair p;
p.Ptr = (ID << 3) | (0x1 << 2) | uint64_t(AS);
return p;
}

uint64_t getDeclID() const {
assert(isDeclID());
return (~Mask & Ptr) >> 3;
}

NamedDecl *getDecl() const {
assert(!isDeclID());
return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
}
AccessSpecifier getAccess() const {
return AccessSpecifier(Mask & Ptr);
}
AccessSpecifier getAccess() const { return AccessSpecifier(ASMask & Ptr); }

void setDecl(NamedDecl *D) {
set(D, getAccess());
Expand All @@ -52,12 +71,18 @@ class DeclAccessPair {
set(getDecl(), AS);
}
void set(NamedDecl *D, AccessSpecifier AS) {
Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
Ptr = uint64_t(AS) | reinterpret_cast<uint64_t>(D);
}

operator NamedDecl*() const { return getDecl(); }
NamedDecl *operator->() const { return getDecl(); }
};

// Make sure DeclAccessPair is pointer-aligned types.
static_assert(alignof(DeclAccessPair) == alignof(void *));
// Make sure DeclAccessPair is still POD.
static_assert(std::is_standard_layout_v<DeclAccessPair> &&
std::is_trivial_v<DeclAccessPair>);
}

#endif
28 changes: 14 additions & 14 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,13 @@ class alignas(8) Decl {
/// Whether this declaration comes from another module unit.
bool isInAnotherModuleUnit() const;

/// Whether the definition of the declaration should be emitted in external
/// sources.
bool shouldEmitInExternalSource() const;

/// Whether this declaration comes from a named module;
bool isInNamedModule() const;

/// Whether this declaration comes from explicit global module.
bool isFromExplicitGlobalModule() const;

Expand Down Expand Up @@ -701,10 +708,7 @@ class alignas(8) Decl {

/// Set the owning module ID. This may only be called for
/// deserialized Decls.
void setOwningModuleID(unsigned ID) {
assert(isFromASTFile() && "Only works on a deserialized declaration");
*((unsigned*)this - 2) = ID;
}
void setOwningModuleID(unsigned ID);

public:
/// Determine the availability of the given declaration.
Expand Down Expand Up @@ -777,19 +781,11 @@ class alignas(8) Decl {

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

/// Retrieve the global ID of the module that owns this particular
/// declaration.
unsigned getOwningModuleID() const {
if (isFromASTFile())
return *((const unsigned*)this - 2);
return 0;
}
unsigned getOwningModuleID() const;

private:
Module *getOwningModuleSlow() const;
Expand Down Expand Up @@ -2148,6 +2144,10 @@ class DeclContext {
getDeclKind() <= Decl::lastRecord;
}

bool isRequiresExprBody() const {
return getDeclKind() == Decl::RequiresExprBody;
}

bool isNamespace() const { return getDeclKind() == Decl::Namespace; }

bool isStdNamespace() const;
Expand Down
18 changes: 17 additions & 1 deletion clang/include/clang/AST/DeclID.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/iterator.h"

#include <climits>

namespace clang {

/// Predefined declaration IDs.
Expand Down Expand Up @@ -107,12 +109,16 @@ class DeclIDBase {
///
/// DeclID should only be used directly in serialization. All other users
/// should use LocalDeclID or GlobalDeclID.
using DeclID = uint32_t;
using DeclID = uint64_t;

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

explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) {
ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32);
}

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

Expand All @@ -124,6 +130,10 @@ class DeclIDBase {

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

unsigned getModuleFileIndex() const { return ID >> 32; }

unsigned getLocalDeclIndex() const;

friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID == RHS.ID;
}
Expand Down Expand Up @@ -156,6 +166,9 @@ class LocalDeclID : public DeclIDBase {
LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
explicit LocalDeclID(DeclID ID) : Base(ID) {}

explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
: Base(LocalID, ModuleFileIndex) {}

LocalDeclID &operator++() {
++ID;
return *this;
Expand All @@ -175,6 +188,9 @@ class GlobalDeclID : public DeclIDBase {
GlobalDeclID() : Base() {}
explicit GlobalDeclID(DeclID ID) : Base(ID) {}

explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
: Base(LocalID, ModuleFileIndex) {}

// For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID
// to a LocalDeclID.
explicit operator LocalDeclID() const { return LocalDeclID(this->ID); }
Expand Down
11 changes: 6 additions & 5 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -3025,9 +3025,10 @@ class OverloadExpr : public Expr {

public:
struct FindResult {
OverloadExpr *Expression;
bool IsAddressOfOperand;
bool HasFormOfMemberPointer;
OverloadExpr *Expression = nullptr;
bool IsAddressOfOperand = false;
bool IsAddressOfOperandWithParen = false;
bool HasFormOfMemberPointer = false;
};

/// Finds the overloaded expression in the given expression \p E of
Expand All @@ -3039,6 +3040,7 @@ class OverloadExpr : public Expr {
assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));

FindResult Result;
bool HasParen = isa<ParenExpr>(E);

E = E->IgnoreParens();
if (isa<UnaryOperator>(E)) {
Expand All @@ -3048,10 +3050,9 @@ class OverloadExpr : public Expr {

Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
Result.IsAddressOfOperand = true;
Result.IsAddressOfOperandWithParen = HasParen;
Result.Expression = Ovl;
} else {
Result.HasFormOfMemberPointer = false;
Result.IsAddressOfOperand = false;
Result.Expression = cast<OverloadExpr>(E);
}

Expand Down
145 changes: 144 additions & 1 deletion clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,149 @@ class OpenACCClause {
virtual ~OpenACCClause() = default;
};

// Represents the 'auto' clause.
class OpenACCAutoClause : public OpenACCClause {
protected:
OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Auto;
}

static OpenACCAutoClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Represents the 'independent' clause.
class OpenACCIndependentClause : public OpenACCClause {
protected:
OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Independent;
}

static OpenACCIndependentClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
// Represents the 'seq' clause.
class OpenACCSeqClause : public OpenACCClause {
protected:
OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Seq;
}

static OpenACCSeqClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
// this provides a basic, do-nothing implementation. We still need to add this
// type to the visitors/etc, as well as get it to take its proper arguments.
class OpenACCGangClause : public OpenACCClause {
protected:
OpenACCGangClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) {
llvm_unreachable("Not yet implemented");
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Gang;
}

static OpenACCGangClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
// this provides a basic, do-nothing implementation. We still need to add this
// type to the visitors/etc, as well as get it to take its proper arguments.
class OpenACCVectorClause : public OpenACCClause {
protected:
OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Vector, BeginLoc, EndLoc) {
llvm_unreachable("Not yet implemented");
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Gang;
}

static OpenACCVectorClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
// this provides a basic, do-nothing implementation. We still need to add this
// type to the visitors/etc, as well as get it to take its proper arguments.
class OpenACCWorkerClause : public OpenACCClause {
protected:
OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) {
llvm_unreachable("Not yet implemented");
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Gang;
}

static OpenACCWorkerClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

/// Represents a clause that has a list of parameters.
class OpenACCClauseWithParams : public OpenACCClause {
/// Location of the '('.
Expand Down Expand Up @@ -724,7 +867,7 @@ template <class Impl> class OpenACCClauseVisitor {
case OpenACCClauseKind::CLAUSE_NAME: \
Visit##CLAUSE_NAME##Clause(*cast<OpenACC##CLAUSE_NAME##Clause>(C)); \
return;
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME) \
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \
case OpenACCClauseKind::ALIAS_NAME: \
Visit##CLAUSE_NAME##Clause(*cast<OpenACC##CLAUSE_NAME##Clause>(C)); \
return;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4000,6 +4000,8 @@ bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(

DEF_TRAVERSE_STMT(OpenACCComputeConstruct,
{ TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
{ TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })

// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
Expand Down
71 changes: 70 additions & 1 deletion clang/include/clang/AST/StmtOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt {
return const_cast<OpenACCAssociatedStmtConstruct *>(this)->children();
}
};

class OpenACCLoopConstruct;
/// This class represents a compute construct, representing a 'Kind' of
/// `parallel', 'serial', or 'kernel'. These constructs are associated with a
/// 'structured block', defined as:
Expand Down Expand Up @@ -165,6 +167,11 @@ class OpenACCComputeConstruct final
}

void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
// Serialization helper function that searches the structured block for 'loop'
// constructs that should be associated with this, and sets their parent
// compute construct to this one. This isn't necessary normally, since we have
// the ability to record the state during parsing.
void findAndSetChildLoops();

public:
static bool classof(const Stmt *T) {
Expand All @@ -176,12 +183,74 @@ class OpenACCComputeConstruct final
static OpenACCComputeConstruct *
Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
SourceLocation DirectiveLoc, SourceLocation EndLoc,
ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock);
ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock,
ArrayRef<OpenACCLoopConstruct *> AssociatedLoopConstructs);

Stmt *getStructuredBlock() { return getAssociatedStmt(); }
const Stmt *getStructuredBlock() const {
return const_cast<OpenACCComputeConstruct *>(this)->getStructuredBlock();
}
};
/// This class represents a 'loop' construct. The 'loop' construct applies to a
/// 'for' loop (or range-for loop), and is optionally associated with a Compute
/// Construct.
class OpenACCLoopConstruct final
: public OpenACCAssociatedStmtConstruct,
public llvm::TrailingObjects<OpenACCLoopConstruct,
const OpenACCClause *> {
// The compute construct this loop is associated with, or nullptr if this is
// an orphaned loop construct, or if it hasn't been set yet. Because we
// construct the directives at the end of their statement, the 'parent'
// construct is not yet available at the time of construction, so this needs
// to be set 'later'.
const OpenACCComputeConstruct *ParentComputeConstruct = nullptr;

friend class ASTStmtWriter;
friend class ASTStmtReader;
friend class ASTContext;
friend class OpenACCComputeConstruct;

OpenACCLoopConstruct(unsigned NumClauses);

OpenACCLoopConstruct(SourceLocation Start, SourceLocation DirLoc,
SourceLocation End,
ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop);
void setLoop(Stmt *Loop);

void setParentComputeConstruct(OpenACCComputeConstruct *CC) {
assert(!ParentComputeConstruct && "Parent already set?");
ParentComputeConstruct = CC;
}

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

static OpenACCLoopConstruct *CreateEmpty(const ASTContext &C,
unsigned NumClauses);

static OpenACCLoopConstruct *
Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation DirLoc,
SourceLocation EndLoc, ArrayRef<const OpenACCClause *> Clauses,
Stmt *Loop);

Stmt *getLoop() { return getAssociatedStmt(); }
const Stmt *getLoop() const {
return const_cast<OpenACCLoopConstruct *>(this)->getLoop();
}

/// OpenACC 3.3 2.9:
/// An orphaned loop construct is a loop construct that is not lexically
/// enclosed within a compute construct. The parent compute construct of a
/// loop construct is the nearest compute construct that lexically contains
/// the loop construct.
bool isOrphanedLoopConstruct() const {
return ParentComputeConstruct == nullptr;
}
const OpenACCComputeConstruct *getParentComputeConstruct() const {
return ParentComputeConstruct;
}
};
} // namespace clang
#endif // LLVM_CLANG_AST_STMTOPENACC_H
5 changes: 0 additions & 5 deletions clang/include/clang/AST/TemplateName.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,6 @@ class TemplateName {

TemplateName getUnderlying() const;

/// Get the template name to substitute when this template name is used as a
/// template template argument. This refers to the most recent declaration of
/// the template, including any default template arguments.
TemplateName getNameToSubstitute() const;

TemplateNameDependence getDependence() const;

/// Determines whether this is a dependent template name.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ class TextNodeDumper
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S);
void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S);
};

} // namespace clang
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,20 @@ class QualType {
/// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool isTriviallyCopyableType(const ASTContext &Context) const;

/// Return true if the type is safe to bitwise copy using memcpy/memmove.
///
/// This is an extension in clang: bitwise cloneable types act as trivially
/// copyable types, meaning their underlying bytes can be safely copied by
/// memcpy or memmove. After the copy, the destination object has the same
/// object representation.
///
/// However, there are cases where it is not safe to copy:
/// - When sanitizers, such as AddressSanitizer, add padding with poison,
/// which can cause issues if those poisoned padding bits are accessed.
/// - Types with Objective-C lifetimes, where specific runtime
/// semantics may not be preserved during a bitwise copy.
bool isBitwiseCloneableType(const ASTContext &Context) const;

/// Return true if this is a trivially copyable type
bool isTriviallyCopyConstructibleType(const ASTContext &Context) const;

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/UnresolvedSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
// temporaries with defaulted ctors are not zero initialized.
UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {}

uint64_t getDeclID() const { return I->getDeclID(); }
NamedDecl *getDecl() const { return I->getDecl(); }
void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
AccessSpecifier getAccess() const { return I->getAccess(); }
Expand Down
16 changes: 12 additions & 4 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -8371,20 +8371,28 @@ AST_MATCHER_P(Stmt, forCallable, internal::Matcher<Decl>, InnerMatcher) {
const auto &CurNode = Stack.back();
Stack.pop_back();
if (const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) {
if (InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) {
BoundNodesTreeBuilder B = *Builder;
if (InnerMatcher.matches(*FuncDeclNode, Finder, &B)) {
*Builder = std::move(B);
return true;
}
} else if (const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) {
BoundNodesTreeBuilder B = *Builder;
if (InnerMatcher.matches(*LambdaExprNode->getCallOperator(), Finder,
Builder)) {
&B)) {
*Builder = std::move(B);
return true;
}
} else if (const auto *ObjCMethodDeclNode = CurNode.get<ObjCMethodDecl>()) {
if (InnerMatcher.matches(*ObjCMethodDeclNode, Finder, Builder)) {
BoundNodesTreeBuilder B = *Builder;
if (InnerMatcher.matches(*ObjCMethodDeclNode, Finder, &B)) {
*Builder = std::move(B);
return true;
}
} else if (const auto *BlockDeclNode = CurNode.get<BlockDecl>()) {
if (InnerMatcher.matches(*BlockDeclNode, Finder, Builder)) {
BoundNodesTreeBuilder B = *Builder;
if (InnerMatcher.matches(*BlockDeclNode, Finder, &B)) {
*Builder = std::move(B);
return true;
}
} else {
Expand Down
47 changes: 47 additions & 0 deletions clang/include/clang/Analysis/FlowSensitive/ASTOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "llvm/ADT/DenseSet.h"
Expand Down Expand Up @@ -80,6 +81,52 @@ class RecordInitListHelper {
std::optional<ImplicitValueInitExpr> ImplicitValueInitForUnion;
};

/// Specialization of `RecursiveASTVisitor` that visits those nodes that are
/// relevant to the dataflow analysis; generally, these are the ones that also
/// appear in the CFG.
/// To start the traversal, call `TraverseStmt()` on the statement or body of
/// the function to analyze. Don't call `TraverseDecl()` on the function itself;
/// this won't work as `TraverseDecl()` contains code to avoid traversing nested
/// functions.
template <class Derived>
class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
public:
bool shouldVisitImplicitCode() { return true; }

bool shouldVisitLambdaBody() const { return false; }

bool TraverseDecl(Decl *D) {
// Don't traverse nested record or function declarations.
// - We won't be analyzing code contained in these anyway
// - We don't model fields that are used only in these nested declaration,
// so trying to propagate a result object to initializers of such fields
// would cause an error.
if (isa_and_nonnull<RecordDecl>(D) || isa_and_nonnull<FunctionDecl>(D))
return true;

return RecursiveASTVisitor<Derived>::TraverseDecl(D);
}

// Don't traverse expressions in unevaluated contexts, as we don't model
// fields that are only used in these.
// Note: The operand of the `noexcept` operator is an unevaluated operand, but
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; }
bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
return true;
}

bool TraverseBindingDecl(BindingDecl *BD) {
// `RecursiveASTVisitor` doesn't traverse holding variables for
// `BindingDecl`s by itself, so we need to tell it to.
if (VarDecl *HoldingVar = BD->getHoldingVar())
TraverseDecl(HoldingVar);
return RecursiveASTVisitor<Derived>::TraverseBindingDecl(BD);
}
};

/// A collection of several types of declarations, all referenced from the same
/// function.
struct ReferencedDecls {
Expand Down
52 changes: 52 additions & 0 deletions clang/include/clang/Basic/ASTSourceDescriptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===- ASTSourceDescriptor.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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines the clang::ASTSourceDescriptor class, which abstracts clang modules
/// and precompiled header files
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H
#define LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H

#include "clang/Basic/Module.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <utility>

namespace clang {

/// Abstracts clang modules and precompiled header files and holds
/// everything needed to generate debug info for an imported module
/// or PCH.
class ASTSourceDescriptor {
StringRef PCHModuleName;
StringRef Path;
StringRef ASTFile;
ASTFileSignature Signature;
Module *ClangModule = nullptr;

public:
ASTSourceDescriptor() = default;
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
ASTFileSignature Signature)
: PCHModuleName(std::move(Name)), Path(std::move(Path)),
ASTFile(std::move(ASTFile)), Signature(Signature) {}
ASTSourceDescriptor(Module &M);

std::string getModuleName() const;
StringRef getPath() const { return Path; }
StringRef getASTFile() const { return ASTFile; }
ASTFileSignature getSignature() const { return Signature; }
Module *getModuleOrNull() const { return ClangModule; }
};

} // namespace clang

#endif // LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3068,7 +3068,8 @@ def M68kRTD: DeclOrTypeAttr {
let Documentation = [M68kRTDDocs];
}

def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86> {
def PreserveNone : DeclOrTypeAttr,
TargetSpecificAttr<TargetArch<!listconcat(TargetAArch64.Arches, TargetAnyX86.Arches)>> {
let Spellings = [Clang<"preserve_none">];
let Subjects = SubjectList<[FunctionLike]>;
let Documentation = [PreserveNoneDocs];
Expand Down Expand Up @@ -4499,6 +4500,7 @@ def HLSLShader : InheritableAttr {
case HLSLShaderAttr::Mesh: return llvm::Triple::Mesh;
case HLSLShaderAttr::Amplification: return llvm::Triple::Amplification;
}
llvm_unreachable("unknown enumeration value");
}
}];
}
Expand Down
17 changes: 10 additions & 7 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5660,18 +5660,21 @@ experimental at this time.
def PreserveNoneDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
On X86-64 target, this attribute changes the calling convention of a function.
On X86-64 and AArch64 targets, this attribute changes the calling convention of a function.
The ``preserve_none`` calling convention tries to preserve as few general
registers as possible. So all general registers are caller saved registers. It
also uses more general registers to pass arguments. This attribute doesn't
impact floating-point registers (XMMs/YMMs). Floating-point registers still
follow the c calling convention. ``preserve_none``'s ABI is still unstable, and
impact floating-point registers. ``preserve_none``'s ABI is still unstable, and
may be changed in the future.

- Only RSP and RBP are preserved by callee.

- Register R12, R13, R14, R15, RDI, RSI, RDX, RCX, R8, R9, R11, and RAX now can
be used to pass function arguments.
- On X86-64, only RSP and RBP are preserved by the callee.
Registers R12, R13, R14, R15, RDI, RSI, RDX, RCX, R8, R9, R11, and RAX now can
be used to pass function arguments. Floating-point registers (XMMs/YMMs) still
follow the C calling convention.
- On AArch64, only LR and FP are preserved by the callee.
Registers X19-X28, X0-X7, and X9-X15 are used to pass function arguments.
X8, X16-X18, SIMD and floating-point registers follow the AAPCS calling
convention.
}];
}

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/BuiltinsAMDGPU.def
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_v2bf16, "V2sV2s*0V2s", "t", "at
TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2bf16, "V2sV2s*1V2s", "t", "atomic-global-pk-add-bf16-inst")
TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2bf16, "V2sV2s*3V2s", "t", "atomic-ds-pk-add-16-insts")
TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2f16, "V2hV2h*3V2h", "t", "atomic-ds-pk-add-16-insts")
TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3UiiUi", "t", "gfx940-insts")
TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3IUiIiIUi", "t", "gfx940-insts")

//===----------------------------------------------------------------------===//
// Deep learning builtins.
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Basic/BuiltinsNVPTX.def
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@
#pragma push_macro("PTX82")
#pragma push_macro("PTX83")
#pragma push_macro("PTX84")
#define PTX84 "ptx84"
#pragma push_macro("PTX85")
#define PTX85 "ptx85"
#define PTX84 "ptx84|" PTX85
#define PTX83 "ptx83|" PTX84
#define PTX82 "ptx82|" PTX83
#define PTX81 "ptx81|" PTX82
Expand Down Expand Up @@ -1094,3 +1096,4 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78))
#pragma pop_macro("PTX82")
#pragma pop_macro("PTX83")
#pragma pop_macro("PTX84")
#pragma pop_macro("PTX85")
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/CharInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ LLVM_READONLY inline bool isRawStringDelimBody(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER | CHAR_LOWER | CHAR_PERIOD | CHAR_DIGIT |
CHAR_UNDER | CHAR_PUNCT)) != 0 &&
c != '(' && c != ')';
c != '(' && c != ')' && c != '\\';
}

enum class EscapeChar {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-sections.
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,reserved,none

CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free.
CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
Expand Down
9 changes: 6 additions & 3 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,18 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string BinutilsVersion;

enum class FramePointerKind {
None, // Omit all frame pointers.
NonLeaf, // Keep non-leaf frame pointers.
All, // Keep all frame pointers.
None, // Omit all frame pointers.
Reserved, // Maintain valid frame pointer chain.
NonLeaf, // Keep non-leaf frame pointers.
All, // Keep all frame pointers.
};

static StringRef getFramePointerKindName(FramePointerKind Kind) {
switch (Kind) {
case FramePointerKind::None:
return "none";
case FramePointerKind::Reserved:
return "reserved";
case FramePointerKind::NonLeaf:
return "non-leaf";
case FramePointerKind::All:
Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Basic/Cuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ enum class CudaVersion {
CUDA_122,
CUDA_123,
CUDA_124,
CUDA_125,
FULLY_SUPPORTED = CUDA_123,
PARTIALLY_SUPPORTED =
CUDA_124, // Partially supported. Proceed with a warning.
CUDA_125, // Partially supported. Proceed with a warning.
NEW = 10000, // Too new. Issue a warning, but allow using it.
};
const char *CudaVersionToString(CudaVersion V);
Expand Down Expand Up @@ -91,6 +92,7 @@ enum class CudaArch {
GFX803,
GFX805,
GFX810,
GFX9_GENERIC,
GFX900,
GFX902,
GFX904,
Expand All @@ -102,23 +104,28 @@ enum class CudaArch {
GFX940,
GFX941,
GFX942,
GFX10_1_GENERIC,
GFX1010,
GFX1011,
GFX1012,
GFX1013,
GFX10_3_GENERIC,
GFX1030,
GFX1031,
GFX1032,
GFX1033,
GFX1034,
GFX1035,
GFX1036,
GFX11_GENERIC,
GFX1100,
GFX1101,
GFX1102,
GFX1103,
GFX1150,
GFX1151,
GFX1152,
GFX12_GENERIC,
GFX1200,
GFX1201,
Generic, // A processor model named 'generic' if the target backend defines a
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
/// default).
std::vector<std::string> VerifyPrefixes;

/// The list of -Wsystem-header-in-module=... options used to override
/// The list of -Wsystem-headers-in-module=... options used to override
/// whether -Wsystem-headers is enabled on a per-module basis.
std::vector<std::string> SystemHeaderWarningsModules;

Expand Down
25 changes: 21 additions & 4 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ def note_using_decl_class_member_workaround : Note<
"a const variable|a constexpr variable}0 instead">;
def err_using_decl_can_not_refer_to_namespace : Error<
"using declaration cannot refer to a namespace">;
def note_namespace_using_decl : Note<
"did you mean 'using namespace'?">;
def warn_cxx17_compat_using_decl_scoped_enumerator: Warning<
"using declaration naming a scoped enumerator is incompatible with "
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
Expand Down Expand Up @@ -6088,9 +6090,9 @@ def err_redefinition_different_concept : Error<
"redefinition of concept %0 with different template parameters or requirements">;
def err_tag_reference_non_tag : Error<
"%select{non-struct type|non-class type|non-union type|non-enum "
"type|typedef|type alias|template|type alias template|template "
"template argument}1 %0 cannot be referenced with a "
"%select{struct|interface|union|class|enum}2 specifier">;
"type|typedef|type alias|template|alias template|template "
"template argument}1 %0 cannot be referenced with the '"
"%select{struct|interface|union|class|enum}2' specifier">;
def err_tag_reference_conflict : Error<
"implicit declaration introduced by elaborated type conflicts with a "
"%select{non-struct type|non-class type|non-union type|non-enum "
Expand Down Expand Up @@ -10082,6 +10084,12 @@ def warn_new_dangling_initializer_list : Warning<
"the allocated initializer list}0 "
"will be destroyed at the end of the full-expression">,
InGroup<DanglingInitializerList>;
def warn_unsupported_lifetime_extension : Warning<
"lifetime extension of "
"%select{temporary|backing array of initializer list}0 created "
"by aggregate initialization using a default member initializer "
"is not yet supported; lifetime of %select{temporary|backing array}0 "
"will end at the end of the full-expression">, InGroup<Dangling>;

// For non-floating point, expressions of the form x == x or x != x
// should result in a warning, since these always evaluate to a constant.
Expand Down Expand Up @@ -12398,7 +12406,10 @@ def err_acc_var_not_pointer_type
def note_acc_expected_pointer_var : Note<"expected variable of pointer type">;
def err_acc_clause_after_device_type
: Error<"OpenACC clause '%0' may not follow a '%1' clause in a "
"compute construct">;
"%select{'%3'|compute}2 construct">;
def err_acc_clause_cannot_combine
: Error<"OpenACC clause '%0' may not appear on the same construct as a "
"'%1' clause on a 'loop' construct">;
def err_acc_reduction_num_gangs_conflict
: Error<
"OpenACC 'reduction' clause may not appear on a 'parallel' construct "
Expand All @@ -12413,6 +12424,12 @@ def err_acc_reduction_composite_type
def err_acc_reduction_composite_member_type :Error<
"OpenACC 'reduction' composite variable must not have non-scalar field">;
def note_acc_reduction_composite_member_loc : Note<"invalid field is here">;
def err_acc_loop_not_for_loop
: Error<"OpenACC 'loop' construct can only be applied to a 'for' loop">;
def note_acc_construct_here : Note<"'%0' construct is here">;
def err_acc_loop_spec_conflict
: Error<"OpenACC clause '%0' on '%1' construct conflicts with previous "
"data dependence clause">;

// AMDGCN builtins diagnostics
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,14 @@ COMPATIBLE_LANGOPT(IncrementalExtensions, 1, 0, " True if we want to process sta

BENIGN_LANGOPT(CheckNew, 1, 0, "Do not assume C++ operator new may not return NULL")

// FIXME: It would be better for us to find a way to encode the state of this
// diagnostic in tablegen so that we can specify a particular diagnostic option
// is disabled or enabled based on other language options or made it easier to
// do this from the compiler invocation without hitting option round-tripping
// issues.
BENIGN_LANGOPT(CheckConstexprFunctionBodies, 1, 1,
"Emit diagnostics for a constexpr function body that can never "
"be used in a constant expression.")
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
Expand Down
26 changes: 0 additions & 26 deletions clang/include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,32 +868,6 @@ class VisibleModuleSet {
unsigned Generation = 0;
};

/// Abstracts clang modules and precompiled header files and holds
/// everything needed to generate debug info for an imported module
/// or PCH.
class ASTSourceDescriptor {
StringRef PCHModuleName;
StringRef Path;
StringRef ASTFile;
ASTFileSignature Signature;
Module *ClangModule = nullptr;

public:
ASTSourceDescriptor() = default;
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
ASTFileSignature Signature)
: PCHModuleName(std::move(Name)), Path(std::move(Path)),
ASTFile(std::move(ASTFile)), Signature(Signature) {}
ASTSourceDescriptor(Module &M);

std::string getModuleName() const;
StringRef getPath() const { return Path; }
StringRef getASTFile() const { return ASTFile; }
ASTFileSignature getSignature() const { return Signature; }
Module *getModuleOrNull() const { return ClangModule; }
};


} // namespace clang

#endif // LLVM_CLANG_BASIC_MODULE_H
25 changes: 14 additions & 11 deletions clang/include/clang/Basic/OpenACCClauses.def
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,42 @@
//
// VISIT_CLAUSE(CLAUSE_NAME)
//
// CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME)
// CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED)

#ifndef CLAUSE_ALIAS
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME)
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, false)
#endif

VISIT_CLAUSE(Auto)
VISIT_CLAUSE(Async)
VISIT_CLAUSE(Attach)
VISIT_CLAUSE(Copy)
CLAUSE_ALIAS(PCopy, Copy)
CLAUSE_ALIAS(PresentOrCopy, Copy)
CLAUSE_ALIAS(PCopy, Copy, true)
CLAUSE_ALIAS(PresentOrCopy, Copy, true)
VISIT_CLAUSE(CopyIn)
CLAUSE_ALIAS(PCopyIn, CopyIn)
CLAUSE_ALIAS(PresentOrCopyIn, CopyIn)
CLAUSE_ALIAS(PCopyIn, CopyIn, true)
CLAUSE_ALIAS(PresentOrCopyIn, CopyIn, true)
VISIT_CLAUSE(CopyOut)
CLAUSE_ALIAS(PCopyOut, CopyOut)
CLAUSE_ALIAS(PresentOrCopyOut, CopyOut)
CLAUSE_ALIAS(PCopyOut, CopyOut, true)
CLAUSE_ALIAS(PresentOrCopyOut, CopyOut, true)
VISIT_CLAUSE(Create)
CLAUSE_ALIAS(PCreate, Create)
CLAUSE_ALIAS(PresentOrCreate, Create)
CLAUSE_ALIAS(PCreate, Create, true)
CLAUSE_ALIAS(PresentOrCreate, Create, true)
VISIT_CLAUSE(Default)
VISIT_CLAUSE(DevicePtr)
VISIT_CLAUSE(DeviceType)
CLAUSE_ALIAS(DType, DeviceType)
CLAUSE_ALIAS(DType, DeviceType, false)
VISIT_CLAUSE(FirstPrivate)
VISIT_CLAUSE(If)
VISIT_CLAUSE(Independent)
VISIT_CLAUSE(NoCreate)
VISIT_CLAUSE(NumGangs)
VISIT_CLAUSE(NumWorkers)
VISIT_CLAUSE(Present)
VISIT_CLAUSE(Private)
VISIT_CLAUSE(Reduction)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(Seq)
VISIT_CLAUSE(VectorLength)
VISIT_CLAUSE(Wait)

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,4 @@ def OpenACCConstructStmt : StmtNode<Stmt, /*abstract=*/1>;
def OpenACCAssociatedStmtConstruct
: StmtNode<OpenACCConstructStmt, /*abstract=*/1>;
def OpenACCComputeConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
def OpenACCLoopConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@ TYPE_TRAIT_2(__reference_converts_from_temporary, ReferenceConvertsFromTemporary
// is not exposed to users.
TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)

TYPE_TRAIT_1(__is_bitwise_cloneable, IsBitwiseCloneable, KEYALL)

// Embarcadero Expression Traits
EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
EXPRESSION_TRAIT(__is_rvalue_expr, IsRValueExpr, KEYCXX)
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/riscv_vector.td
Original file line number Diff line number Diff line change
Expand Up @@ -2637,7 +2637,8 @@ let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vbrev : RVVOutBuiltinSetZvbb;
defm vclz : RVVOutBuiltinSetZvbb;
defm vctz : RVVOutBuiltinSetZvbb;
defm vcpopv : RVVOutBuiltinSetZvbb;
let IRName = "vcpopv", MaskedIRName = "vcpopv_mask" in
defm vcpop : RVVOutBuiltinSetZvbb;
let OverloadedName = "vwsll" in
defm vwsll : RVVSignedWidenBinBuiltinSetVwsll;
}
Expand Down
24 changes: 21 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,17 @@ multiclass BoolMOption<string flag_base, KeyPathAndMacro kpm,
Group<m_Group>;
}

/// Creates a BoolOption where both of the flags are prefixed with "W", are in
/// the Group<W_Group>.
/// Used for -cc1 frontend options. Driver-only options do not map to
/// CompilerInvocation.
multiclass BoolWOption<string flag_base, KeyPathAndMacro kpm,
Default default, FlagDef flag1, FlagDef flag2,
BothFlags both = BothFlags<[]>> {
defm NAME : BoolOption<"W", flag_base, kpm, default, flag1, flag2, both>,
Group<W_Group>;
}

// Works like BoolOption except without marshalling
multiclass BoolOptionWithoutMarshalling<string prefix = "", string spelling_base,
FlagDef flag1_base, FlagDef flag2_base,
Expand Down Expand Up @@ -606,6 +617,7 @@ defvar cpp11 = LangOpts<"CPlusPlus11">;
defvar cpp14 = LangOpts<"CPlusPlus14">;
defvar cpp17 = LangOpts<"CPlusPlus17">;
defvar cpp20 = LangOpts<"CPlusPlus20">;
defvar cpp23 = LangOpts<"CPlusPlus23">;
defvar c99 = LangOpts<"C99">;
defvar c23 = LangOpts<"C23">;
defvar lang_std = LangOpts<"LangStd">;
Expand Down Expand Up @@ -961,6 +973,12 @@ def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>,
HelpText<"Enable warnings for deprecated constructs and define __DEPRECATED">;
def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>,
Visibility<[ClangOption, CC1Option]>;
defm invalid_constexpr : BoolWOption<"invalid-constexpr",
LangOpts<"CheckConstexprFunctionBodies">,
Default<!strconcat("!", cpp23.KeyPath)>,
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Disable">,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
BothFlags<[], [ClangOption, CC1Option], " checking of constexpr function bodies for validity within a constant expression context">>;
def Wl_COMMA : CommaJoined<["-"], "Wl,">, Visibility<[ClangOption, FlangOption]>,
Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass the comma separated arguments in <arg> to the linker">,
Expand Down Expand Up @@ -3574,7 +3592,7 @@ def fopenmp_offload_mandatory : Flag<["-"], "fopenmp-offload-mandatory">, Group<
HelpText<"Do not create a host fallback if offloading to the device fails.">,
MarshallingInfoFlag<LangOpts<"OpenMPOffloadMandatory">>;
def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group<f_Group>,
Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Force behvaior as if the user specified pragma omp requires unified_shared_memory.">,
MarshallingInfoFlag<LangOpts<"OpenMPForceUSM">>;
def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group<f_Group>,
Expand Down Expand Up @@ -7706,8 +7724,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
MarshallingInfoFlag<LangOpts<"PIE">>;

def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,reserved,none">,
NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>,
MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;


Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ class ToolChain {

/// Executes the given \p Executable and returns the stdout.
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
executeToolChainProgram(StringRef Executable) const;
executeToolChainProgram(StringRef Executable,
unsigned SecondsToWait = 0) const;

void setTripleEnvironment(llvm::Triple::EnvironmentType Env);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H

#include "clang/Basic/Module.h"
#include "clang/ExtractAPI/API.h"
#include "clang/ExtractAPI/APIIgnoresList.h"
#include "clang/ExtractAPI/Serialization/APISetVisitor.h"
Expand Down
68 changes: 34 additions & 34 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,8 @@ struct FormatStyle {
enum ShortFunctionStyle : int8_t {
/// Never merge functions into a single line.
SFS_None,
/// Only merge functions defined inside a class. Same as "inline",
/// except it does not implies "empty": i.e. top level empty functions
/// Only merge functions defined inside a class. Same as ``inline``,
/// except it does not implies ``empty``: i.e. top level empty functions
/// are not merged either.
/// \code
/// class Foo {
Expand All @@ -836,7 +836,7 @@ struct FormatStyle {
/// }
/// \endcode
SFS_Empty,
/// Only merge functions defined inside a class. Implies "empty".
/// Only merge functions defined inside a class. Implies ``empty``.
/// \code
/// class Foo {
/// void f() { foo(); }
Expand Down Expand Up @@ -1167,7 +1167,7 @@ struct FormatStyle {
///
/// In the .clang-format configuration file, this can be configured like:
/// \code{.yaml}
/// AttributeMacros: ['__capability', '__output', '__unused']
/// AttributeMacros: [__capability, __output, __unused]
/// \endcode
///
/// \version 12
Expand Down Expand Up @@ -2631,7 +2631,7 @@ struct FormatStyle {
///
/// In the .clang-format configuration file, this can be configured like:
/// \code{.yaml}
/// ForEachMacros: ['RANGES_FOR', 'FOREACH']
/// ForEachMacros: [RANGES_FOR, FOREACH]
/// \endcode
///
/// For example: BOOST_FOREACH.
Expand All @@ -2653,7 +2653,7 @@ struct FormatStyle {
///
/// In the .clang-format configuration file, this can be configured like:
/// \code{.yaml}
/// IfMacros: ['IF']
/// IfMacros: [IF]
/// \endcode
///
/// For example: `KJ_IF_MAYBE
Expand Down Expand Up @@ -3030,7 +3030,7 @@ struct FormatStyle {
/// in the following yaml example. This will result in imports being
/// formatted as in the Java example below.
/// \code{.yaml}
/// JavaImportGroups: ['com.example', 'com', 'org']
/// JavaImportGroups: [com.example, com, org]
/// \endcode
///
/// \code{.java}
Expand Down Expand Up @@ -3086,7 +3086,7 @@ struct FormatStyle {
/// VeryLongImportsAreAnnoying,
/// VeryLongImportsAreAnnoying,
/// VeryLongImportsAreAnnoying,
/// } from 'some/module.js'
/// } from "some/module.js"
///
/// false:
/// import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js"
Expand Down Expand Up @@ -3615,7 +3615,7 @@ struct FormatStyle {
/// Change specifiers/qualifiers to be aligned based on ``QualifierOrder``.
/// With:
/// \code{.yaml}
/// QualifierOrder: ['inline', 'static', 'type', 'const']
/// QualifierOrder: [inline, static, type, const]
/// \endcode
///
/// \code
Expand Down Expand Up @@ -3650,15 +3650,15 @@ struct FormatStyle {
/// * type
///
/// \note
/// it MUST contain 'type'.
/// It **must** contain ``type``.
/// \endnote
///
/// Items to the left of 'type' will be placed to the left of the type and
/// aligned in the order supplied. Items to the right of 'type' will be
/// Items to the left of ``type`` will be placed to the left of the type and
/// aligned in the order supplied. Items to the right of ``type`` will be
/// placed to the right of the type and aligned in the order supplied.
///
/// \code{.yaml}
/// QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ]
/// QualifierOrder: [inline, static, type, const, volatile]
/// \endcode
/// \version 14
std::vector<std::string> QualifierOrder;
Expand Down Expand Up @@ -3692,10 +3692,10 @@ struct FormatStyle {
/// name will be reformatted assuming the specified language based on the
/// style for that language defined in the .clang-format file. If no style has
/// been defined in the .clang-format file for the specific language, a
/// predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not
/// found, the formatting is based on llvm style. A matching delimiter takes
/// precedence over a matching enclosing function name for determining the
/// language of the raw string contents.
/// predefined style given by ``BasedOnStyle`` is used. If ``BasedOnStyle`` is
/// not found, the formatting is based on ``LLVM`` style. A matching delimiter
/// takes precedence over a matching enclosing function name for determining
/// the language of the raw string contents.
///
/// If a canonical delimiter is specified, occurrences of other delimiters for
/// the same language will be updated to the canonical if possible.
Expand All @@ -3708,17 +3708,17 @@ struct FormatStyle {
/// RawStringFormats:
/// - Language: TextProto
/// Delimiters:
/// - 'pb'
/// - 'proto'
/// - pb
/// - proto
/// EnclosingFunctions:
/// - 'PARSE_TEXT_PROTO'
/// - PARSE_TEXT_PROTO
/// BasedOnStyle: google
/// - Language: Cpp
/// Delimiters:
/// - 'cc'
/// - 'cpp'
/// BasedOnStyle: llvm
/// CanonicalDelimiter: 'cc'
/// - cc
/// - cpp
/// BasedOnStyle: LLVM
/// CanonicalDelimiter: cc
/// \endcode
/// \version 6
std::vector<RawStringFormat> RawStringFormats;
Expand Down Expand Up @@ -4046,7 +4046,7 @@ struct FormatStyle {
///
/// This determines the maximum length of short namespaces by counting
/// unwrapped lines (i.e. containing neither opening nor closing
/// namespace brace) and makes "FixNamespaceComments" omit adding
/// namespace brace) and makes ``FixNamespaceComments`` omit adding
/// end comments for those.
/// \code
/// ShortNamespaceLines: 1 vs. ShortNamespaceLines: 0
Expand Down Expand Up @@ -4138,7 +4138,7 @@ struct FormatStyle {
/// \endcode
SUD_Never,
/// Using declarations are sorted in the order defined as follows:
/// Split the strings by "::" and discard any initial empty strings. Sort
/// Split the strings by ``::`` and discard any initial empty strings. Sort
/// the lists of names lexicographically, and within those groups, names are
/// in case-insensitive lexicographic order.
/// \code
Expand All @@ -4150,7 +4150,7 @@ struct FormatStyle {
/// \endcode
SUD_Lexicographic,
/// Using declarations are sorted in the order defined as follows:
/// Split the strings by "::" and discard any initial empty strings. The
/// Split the strings by ``::`` and discard any initial empty strings. The
/// last element of each list is a non-namespace name; all others are
/// namespace names. Sort the lists of names lexicographically, where the
/// sort order of individual names is that all non-namespace names come
Expand Down Expand Up @@ -4186,7 +4186,7 @@ struct FormatStyle {
/// \version 9
bool SpaceAfterLogicalNot;

/// If \c true, a space will be inserted after the 'template' keyword.
/// If \c true, a space will be inserted after the ``template`` keyword.
/// \code
/// true: false:
/// template <int> void foo(); vs. template<int> void foo();
Expand Down Expand Up @@ -4316,7 +4316,7 @@ struct FormatStyle {
/// \endcode
SBPO_ControlStatementsExceptControlMacros,
/// Put a space before opening parentheses only if the parentheses are not
/// empty i.e. '()'
/// empty.
/// \code
/// void() {
/// if (true) {
Expand Down Expand Up @@ -4668,7 +4668,7 @@ struct FormatStyle {
/// x = ( int32 )y vs. x = (int32)y
/// \endcode
bool InCStyleCasts;
/// Put a space in parentheses only if the parentheses are empty i.e. '()'
/// Insert a space in empty parentheses, i.e. ``()``.
/// \code
/// true: false:
/// void f( ) { vs. void f() {
Expand Down Expand Up @@ -4804,11 +4804,11 @@ struct FormatStyle {
/// For example the configuration,
/// \code{.yaml}
/// TableGenBreakInsideDAGArg: BreakAll
/// TableGenBreakingDAGArgOperators: ['ins', 'outs']
/// TableGenBreakingDAGArgOperators: [ins, outs]
/// \endcode
///
/// makes the line break only occurs inside DAGArgs beginning with the
/// specified identifiers 'ins' and 'outs'.
/// specified identifiers ``ins`` and ``outs``.
///
/// \code
/// let DAGArgIns = (ins
Expand Down Expand Up @@ -4873,7 +4873,7 @@ struct FormatStyle {
///
/// In the .clang-format configuration file, this can be configured like:
/// \code{.yaml}
/// TypenameMacros: ['STACK_OF', 'LIST']
/// TypenameMacros: [STACK_OF, LIST]
/// \endcode
///
/// For example: OpenSSL STACK_OF, BSD LIST_ENTRY.
Expand Down Expand Up @@ -4929,7 +4929,7 @@ struct FormatStyle {
///
/// In the .clang-format configuration file, this can be configured like:
/// \code{.yaml}
/// WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE']
/// WhitespaceSensitiveMacros: [STRINGIZE, PP_STRINGIZE]
/// \endcode
///
/// For example: BOOST_PP_STRINGIZE
Expand Down
156 changes: 156 additions & 0 deletions clang/include/clang/Sema/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@
#ifndef LLVM_CLANG_SEMA_ATTR_H
#define LLVM_CLANG_SEMA_ATTR_H

#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/Support/Casting.h"

namespace clang {
Expand All @@ -32,5 +41,152 @@ inline bool isFunctionOrMethodOrBlockForAttrSubject(const Decl *D) {
return isFuncOrMethodForAttrSubject(D) || llvm::isa<BlockDecl>(D);
}

/// Return true if the given decl has a declarator that should have
/// been processed by Sema::GetTypeForDeclarator.
inline bool hasDeclarator(const Decl *D) {
// In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) ||
isa<TypedefNameDecl>(D) || isa<ObjCPropertyDecl>(D);
}

/// hasFunctionProto - Return true if the given decl has a argument
/// information. This decl should have already passed
/// isFuncOrMethodForAttrSubject or isFunctionOrMethodOrBlockForAttrSubject.
inline bool hasFunctionProto(const Decl *D) {
if (const FunctionType *FnTy = D->getFunctionType())
return isa<FunctionProtoType>(FnTy);
return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
}

/// getFunctionOrMethodNumParams - Return number of function or method
/// parameters. It is an error to call this on a K&R function (use
/// hasFunctionProto first).
inline unsigned getFunctionOrMethodNumParams(const Decl *D) {
if (const FunctionType *FnTy = D->getFunctionType())
return cast<FunctionProtoType>(FnTy)->getNumParams();
if (const auto *BD = dyn_cast<BlockDecl>(D))
return BD->getNumParams();
return cast<ObjCMethodDecl>(D)->param_size();
}

inline const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
unsigned Idx) {
if (const auto *FD = dyn_cast<FunctionDecl>(D))
return FD->getParamDecl(Idx);
if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
return MD->getParamDecl(Idx);
if (const auto *BD = dyn_cast<BlockDecl>(D))
return BD->getParamDecl(Idx);
return nullptr;
}

inline QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
if (const FunctionType *FnTy = D->getFunctionType())
return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
if (const auto *BD = dyn_cast<BlockDecl>(D))
return BD->getParamDecl(Idx)->getType();

return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
}

inline SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
if (auto *PVD = getFunctionOrMethodParam(D, Idx))
return PVD->getSourceRange();
return SourceRange();
}

inline QualType getFunctionOrMethodResultType(const Decl *D) {
if (const FunctionType *FnTy = D->getFunctionType())
return FnTy->getReturnType();
return cast<ObjCMethodDecl>(D)->getReturnType();
}

inline SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
if (const auto *FD = dyn_cast<FunctionDecl>(D))
return FD->getReturnTypeSourceRange();
if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
return MD->getReturnTypeSourceRange();
return SourceRange();
}

inline bool isFunctionOrMethodVariadic(const Decl *D) {
if (const FunctionType *FnTy = D->getFunctionType())
return cast<FunctionProtoType>(FnTy)->isVariadic();
if (const auto *BD = dyn_cast<BlockDecl>(D))
return BD->isVariadic();
return cast<ObjCMethodDecl>(D)->isVariadic();
}

inline bool isInstanceMethod(const Decl *D) {
if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
return MethodDecl->isInstance();
return false;
}

/// Diagnose mutually exclusive attributes when present on a given
/// declaration. Returns true if diagnosed.
template <typename AttrTy>
bool checkAttrMutualExclusion(SemaBase &S, Decl *D, const ParsedAttr &AL) {
if (const auto *A = D->getAttr<AttrTy>()) {
S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
<< AL << A
<< (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
S.Diag(A->getLocation(), diag::note_conflicting_attribute);
return true;
}
return false;
}

template <typename AttrTy>
bool checkAttrMutualExclusion(SemaBase &S, Decl *D, const Attr &AL) {
if (const auto *A = D->getAttr<AttrTy>()) {
S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible)
<< &AL << A
<< (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
Diag(A->getLocation(), diag::note_conflicting_attribute);
return true;
}
return false;
}

template <typename... DiagnosticArgs>
const SemaBase::SemaDiagnosticBuilder &
appendDiagnostics(const SemaBase::SemaDiagnosticBuilder &Bldr) {
return Bldr;
}

template <typename T, typename... DiagnosticArgs>
const SemaBase::SemaDiagnosticBuilder &
appendDiagnostics(const SemaBase::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
DiagnosticArgs &&...ExtraArgs) {
return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
std::forward<DiagnosticArgs>(ExtraArgs)...);
}

/// Applies the given attribute to the Decl without performing any
/// additional semantic checking.
template <typename AttrType>
void handleSimpleAttribute(SemaBase &S, Decl *D,
const AttributeCommonInfo &CI) {
D->addAttr(::new (S.getASTContext()) AttrType(S.getASTContext(), CI));
}

/// Add an attribute @c AttrType to declaration @c D, provided that
/// @c PassesCheck is true.
/// Otherwise, emit diagnostic @c DiagID, passing in all parameters
/// specified in @c ExtraArgs.
template <typename AttrType, typename... DiagnosticArgs>
void handleSimpleAttributeOrDiagnose(SemaBase &S, Decl *D,
const AttributeCommonInfo &CI,
bool PassesCheck, unsigned DiagID,
DiagnosticArgs &&...ExtraArgs) {
if (!PassesCheck) {
SemaBase::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
return;
}
handleSimpleAttribute<AttrType>(S, D, CI);
}

} // namespace clang
#endif // LLVM_CLANG_SEMA_ATTR_H
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/Initialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class alignas(8) InitializedEntity {
struct C Capture;
};

InitializedEntity() {};
InitializedEntity() {}

/// Create the initialization entity for a variable.
InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,8 @@ class Sema;
/// object argument.
bool IgnoreObjectArgument : 1;

bool TookAddressOfOverload : 1;

/// True if the candidate was found using ADL.
CallExpr::ADLCallKind IsADLCandidate : 1;

Expand Down Expand Up @@ -999,6 +1001,10 @@ class Sema;
/// Initialization of an object of class type by constructor,
/// using either a parenthesized or braced list of arguments.
CSK_InitByConstructor,

/// C++ [over.match.call.general]
/// Resolve a call through the address of an overload set.
CSK_AddressOfOverloadSet,
};

/// Information about operator rewrites to consider when adding operator
Expand Down
100 changes: 82 additions & 18 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TypeTraits.h"
#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/Sema/Attr.h"
#include "clang/Sema/CleanupInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ExternalSemaSource.h"
Expand Down Expand Up @@ -171,21 +172,26 @@ class PseudoObjectExpr;
class QualType;
class SemaAMDGPU;
class SemaARM;
class SemaAVR;
class SemaBPF;
class SemaCodeCompletion;
class SemaCUDA;
class SemaHLSL;
class SemaHexagon;
class SemaLoongArch;
class SemaM68k;
class SemaMIPS;
class SemaMSP430;
class SemaNVPTX;
class SemaObjC;
class SemaOpenACC;
class SemaOpenCL;
class SemaOpenMP;
class SemaPPC;
class SemaPseudoObject;
class SemaRISCV;
class SemaSYCL;
class SemaSwift;
class SemaSystemZ;
class SemaWasm;
class SemaX86;
Expand Down Expand Up @@ -1011,6 +1017,11 @@ class Sema final : public SemaBase {
return *ARMPtr;
}

SemaAVR &AVR() {
assert(AVRPtr);
return *AVRPtr;
}

SemaBPF &BPF() {
assert(BPFPtr);
return *BPFPtr;
Expand Down Expand Up @@ -1041,11 +1052,21 @@ class Sema final : public SemaBase {
return *LoongArchPtr;
}

SemaM68k &M68k() {
assert(M68kPtr);
return *M68kPtr;
}

SemaMIPS &MIPS() {
assert(MIPSPtr);
return *MIPSPtr;
}

SemaMSP430 &MSP430() {
assert(MSP430Ptr);
return *MSP430Ptr;
}

SemaNVPTX &NVPTX() {
assert(NVPTXPtr);
return *NVPTXPtr;
Expand All @@ -1061,6 +1082,11 @@ class Sema final : public SemaBase {
return *OpenACCPtr;
}

SemaOpenCL &OpenCL() {
assert(OpenCLPtr);
return *OpenCLPtr;
}

SemaOpenMP &OpenMP() {
assert(OpenMPPtr && "SemaOpenMP is dead");
return *OpenMPPtr;
Expand All @@ -1086,6 +1112,11 @@ class Sema final : public SemaBase {
return *SYCLPtr;
}

SemaSwift &Swift() {
assert(SwiftPtr);
return *SwiftPtr;
}

SemaSystemZ &SystemZ() {
assert(SystemZPtr);
return *SystemZPtr;
Expand Down Expand Up @@ -1133,21 +1164,26 @@ class Sema final : public SemaBase {

std::unique_ptr<SemaAMDGPU> AMDGPUPtr;
std::unique_ptr<SemaARM> ARMPtr;
std::unique_ptr<SemaAVR> AVRPtr;
std::unique_ptr<SemaBPF> BPFPtr;
std::unique_ptr<SemaCodeCompletion> CodeCompletionPtr;
std::unique_ptr<SemaCUDA> CUDAPtr;
std::unique_ptr<SemaHLSL> HLSLPtr;
std::unique_ptr<SemaHexagon> HexagonPtr;
std::unique_ptr<SemaLoongArch> LoongArchPtr;
std::unique_ptr<SemaM68k> M68kPtr;
std::unique_ptr<SemaMIPS> MIPSPtr;
std::unique_ptr<SemaMSP430> MSP430Ptr;
std::unique_ptr<SemaNVPTX> NVPTXPtr;
std::unique_ptr<SemaObjC> ObjCPtr;
std::unique_ptr<SemaOpenACC> OpenACCPtr;
std::unique_ptr<SemaOpenCL> OpenCLPtr;
std::unique_ptr<SemaOpenMP> OpenMPPtr;
std::unique_ptr<SemaPPC> PPCPtr;
std::unique_ptr<SemaPseudoObject> PseudoObjectPtr;
std::unique_ptr<SemaRISCV> RISCVPtr;
std::unique_ptr<SemaSYCL> SYCLPtr;
std::unique_ptr<SemaSwift> SwiftPtr;
std::unique_ptr<SemaSystemZ> SystemZPtr;
std::unique_ptr<SemaWasm> WasmPtr;
std::unique_ptr<SemaX86> X86Ptr;
Expand Down Expand Up @@ -3711,8 +3747,6 @@ class Sema final : public SemaBase {
const AttributeCommonInfo &CI,
const IdentifierInfo *Ident);
MinSizeAttr *mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI);
SwiftNameAttr *mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
StringRef Name);
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D,
const AttributeCommonInfo &CI);
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);
Expand All @@ -3726,8 +3760,6 @@ class Sema final : public SemaBase {
const ParsedAttr &attr, CallingConv &CC, const FunctionDecl *FD = nullptr,
CUDAFunctionTarget CFT = CUDAFunctionTarget::InvalidTarget);

void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
ParameterABI ABI);
bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value);

/// Create an CUDALaunchBoundsAttr attribute.
Expand All @@ -3742,20 +3774,6 @@ class Sema final : public SemaBase {
Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks);

enum class RetainOwnershipKind { NS, CF, OS };
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
RetainOwnershipKind K, bool IsTemplateInstantiation);

bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);

/// Do a check to make sure \p Name looks like a legal argument for the
/// swift_name attribute applied to decl \p D. Raise a diagnostic if the name
/// is invalid for the given declaration.
///
/// \p AL is used to provide caret diagnostics in case of a malformed name.
///
/// \returns true if the name is a valid swift name for \p D, false otherwise.
bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc,
const ParsedAttr &AL, bool IsAsync);

UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
StringRef UuidAsWritten, MSGuidDecl *GuidDecl);
Expand Down Expand Up @@ -3825,6 +3843,52 @@ class Sema final : public SemaBase {

void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);

/// Check if IdxExpr is a valid parameter index for a function or
/// instance method D. May output an error.
///
/// \returns true if IdxExpr is a valid index.
template <typename AttrInfo>
bool checkFunctionOrMethodParameterIndex(const Decl *D, const AttrInfo &AI,
unsigned AttrArgNum,
const Expr *IdxExpr, ParamIdx &Idx,
bool CanIndexImplicitThis = false) {
assert(isFunctionOrMethodOrBlockForAttrSubject(D));

// In C++ the implicit 'this' function parameter also counts.
// Parameters are counted from one.
bool HP = hasFunctionProto(D);
bool HasImplicitThisParam = isInstanceMethod(D);
bool IV = HP && isFunctionOrMethodVariadic(D);
unsigned NumParams =
(HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;

std::optional<llvm::APSInt> IdxInt;
if (IdxExpr->isTypeDependent() ||
!(IdxInt = IdxExpr->getIntegerConstantExpr(Context))) {
Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
<< &AI << AttrArgNum << AANT_ArgumentIntegerConstant
<< IdxExpr->getSourceRange();
return false;
}

unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX);
if (IdxSource < 1 || (!IV && IdxSource > NumParams)) {
Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
<< &AI << AttrArgNum << IdxExpr->getSourceRange();
return false;
}
if (HasImplicitThisParam && !CanIndexImplicitThis) {
if (IdxSource == 1) {
Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
<< &AI << IdxExpr->getSourceRange();
return false;
}
}

Idx = ParamIdx(IdxSource, D);
return true;
}

///@}

//
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Sema/SemaARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
#ifndef LLVM_CLANG_SEMA_SEMAARM_H
#define LLVM_CLANG_SEMA_SEMAARM_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/SmallVector.h"
#include <tuple>

namespace clang {
class ParsedAttr;

class SemaARM : public SemaBase {
public:
Expand Down Expand Up @@ -54,6 +56,15 @@ class SemaARM : public SemaBase {
bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum,
unsigned ExpectedFieldNum, bool AllowName);
bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);

bool MveAliasValid(unsigned BuiltinID, StringRef AliasName);
bool CdeAliasValid(unsigned BuiltinID, StringRef AliasName);
bool SveAliasValid(unsigned BuiltinID, StringRef AliasName);
bool SmeAliasValid(unsigned BuiltinID, StringRef AliasName);
void handleBuiltinAliasAttr(Decl *D, const ParsedAttr &AL);
void handleNewAttr(Decl *D, const ParsedAttr &AL);
void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL);
void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
};

SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
Expand Down
32 changes: 32 additions & 0 deletions clang/include/clang/Sema/SemaAVR.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===----- SemaAVR.h ------- AVR target-specific routines -----*- 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
//
//===----------------------------------------------------------------------===//
/// \file
/// This file declares semantic analysis functions specific to AVR.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMAAVR_H
#define LLVM_CLANG_SEMA_SEMAAVR_H

#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaAVR : public SemaBase {
public:
SemaAVR(Sema &S);

void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
void handleSignalAttr(Decl *D, const ParsedAttr &AL);
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMAAVR_H
7 changes: 7 additions & 0 deletions clang/include/clang/Sema/SemaBPF.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@
#ifndef LLVM_CLANG_SEMA_SEMABPF_H
#define LLVM_CLANG_SEMA_SEMABPF_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;

class SemaBPF : public SemaBase {
public:
SemaBPF(Sema &S);

bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);

void handlePreserveAIRecord(RecordDecl *RD);
void handlePreserveAccessIndexAttr(Decl *D, const ParsedAttr &AL);
};
} // namespace clang

Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <initializer_list>

namespace clang {
class ParsedAttr;

class SemaHLSL : public SemaBase {
public:
Expand All @@ -50,6 +51,13 @@ class SemaHLSL : public SemaBase {
const Attr *A, HLSLShaderAttr::ShaderType Stage,
std::initializer_list<HLSLShaderAttr::ShaderType> AllowedStages);
void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU);

void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL);
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
void handleShaderAttr(Decl *D, const ParsedAttr &AL);
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);
};

} // namespace clang
Expand Down
30 changes: 30 additions & 0 deletions clang/include/clang/Sema/SemaM68k.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----- SemaM68k.h ------ M68k target-specific routines ----*- 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
//
//===----------------------------------------------------------------------===//
/// \file
/// This file declares semantic analysis functions specific to M68k.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMAM68K_H
#define LLVM_CLANG_SEMA_SEMAM68K_H

#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaM68k : public SemaBase {
public:
SemaM68k(Sema &S);

void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
};
} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMAM68K_H
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/SemaMIPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
#ifndef LLVM_CLANG_SEMA_SEMAMIPS_H
#define LLVM_CLANG_SEMA_SEMAMIPS_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;

class SemaMIPS : public SemaBase {
public:
SemaMIPS(Sema &S);
Expand All @@ -27,6 +30,7 @@ class SemaMIPS : public SemaBase {
bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);
bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall);
void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
};
} // namespace clang

Expand Down
30 changes: 30 additions & 0 deletions clang/include/clang/Sema/SemaMSP430.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----- SemaMSP430.h --- MSP430 target-specific routines ---*- 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
//
//===----------------------------------------------------------------------===//
/// \file
/// This file declares semantic analysis functions specific to MSP430.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMAMSP430_H
#define LLVM_CLANG_SEMA_SEMAMSP430_H

#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaMSP430 : public SemaBase {
public:
SemaMSP430(Sema &S);

void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
};
} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMAMSP430_H
52 changes: 51 additions & 1 deletion clang/include/clang/Sema/SemaObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Redeclaration.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"
Expand All @@ -45,6 +44,7 @@
namespace clang {

enum class CheckedConversionKind;
class ParsedAttr;
struct SkipBodyInfo;

class SemaObjC : public SemaBase {
Expand Down Expand Up @@ -1007,6 +1007,56 @@ class SemaObjC : public SemaBase {
ObjCInterfaceDecl *IDecl);

///@}

//
//
// -------------------------------------------------------------------------
//
//

/// \name ObjC Attributes
/// Implementations are in SemaObjC.cpp
///@{

bool isNSStringType(QualType T, bool AllowNSAttributedString = false);
bool isCFStringType(QualType T);

void handleIBOutlet(Decl *D, const ParsedAttr &AL);
void handleIBOutletCollection(Decl *D, const ParsedAttr &AL);

void handleSuppresProtocolAttr(Decl *D, const ParsedAttr &AL);
void handleDirectAttr(Decl *D, const ParsedAttr &AL);
void handleDirectMembersAttr(Decl *D, const ParsedAttr &AL);
void handleMethodFamilyAttr(Decl *D, const ParsedAttr &AL);
void handleNSObject(Decl *D, const ParsedAttr &AL);
void handleIndependentClass(Decl *D, const ParsedAttr &AL);
void handleBlocksAttr(Decl *D, const ParsedAttr &AL);
void handleReturnsInnerPointerAttr(Decl *D, const ParsedAttr &Attrs);
void handleXReturnsXRetainedAttr(Decl *D, const ParsedAttr &AL);
void handleRequiresSuperAttr(Decl *D, const ParsedAttr &Attrs);
void handleNSErrorDomain(Decl *D, const ParsedAttr &Attr);
void handleBridgeAttr(Decl *D, const ParsedAttr &AL);
void handleBridgeMutableAttr(Decl *D, const ParsedAttr &AL);
void handleBridgeRelatedAttr(Decl *D, const ParsedAttr &AL);
void handleDesignatedInitializer(Decl *D, const ParsedAttr &AL);
void handleRuntimeName(Decl *D, const ParsedAttr &AL);
void handleBoxable(Decl *D, const ParsedAttr &AL);
void handleOwnershipAttr(Decl *D, const ParsedAttr &AL);
void handlePreciseLifetimeAttr(Decl *D, const ParsedAttr &AL);
void handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL);

void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
Sema::RetainOwnershipKind K,
bool IsTemplateInstantiation);

/// \return whether the parameter is a pointer to OSObject pointer.
bool isValidOSObjectOutParameter(const Decl *D);
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);

Sema::RetainOwnershipKind
parsedAttrToRetainOwnershipKind(const ParsedAttr &AL);

///@}
};

} // namespace clang
Expand Down
27 changes: 26 additions & 1 deletion clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_CLANG_SEMA_SEMAOPENACC_H

#include "clang/AST/DeclGroup.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
Expand All @@ -25,6 +26,15 @@ namespace clang {
class OpenACCClause;

class SemaOpenACC : public SemaBase {
private:
/// A collection of loop constructs in the compute construct scope that
/// haven't had their 'parent' compute construct set yet. Entires will only be
/// made to this list in the case where we know the loop isn't an orphan.
llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;
/// Whether we are inside of a compute construct, and should add loops to the
/// above collection.
bool InsideComputeConstruct = false;

public:
// Redeclaration of the version in OpenACCClause.h.
using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
Expand Down Expand Up @@ -394,7 +404,8 @@ class SemaOpenACC : public SemaBase {
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
/// Called when we encounter an associated statement for our construct, this
/// should check legality of the statement as it appertains to this Construct.
StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt);
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc,
OpenACCDirectiveKind K, StmtResult AssocStmt);

/// Called after the directive has been completely parsed, including the
/// declaration group or associated statement.
Expand Down Expand Up @@ -431,6 +442,20 @@ class SemaOpenACC : public SemaBase {
Expr *LowerBound,
SourceLocation ColonLocFirst, Expr *Length,
SourceLocation RBLoc);

/// Helper type for the registration/assignment of constructs that need to
/// 'know' about their parent constructs and hold a reference to them, such as
/// Loop needing its parent construct.
class AssociatedStmtRAII {
SemaOpenACC &SemaRef;
bool WasInsideComputeConstruct;
OpenACCDirectiveKind DirKind;
llvm::SmallVector<OpenACCLoopConstruct *> ParentlessLoopConstructs;

public:
AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind);
~AssociatedStmtRAII();
};
};

} // namespace clang
Expand Down
35 changes: 35 additions & 0 deletions clang/include/clang/Sema/SemaOpenCL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===----- SemaOpenCL.h --- Semantic Analysis for OpenCL constructs -------===//
//
// 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
/// This file declares semantic analysis routines for OpenCL.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMAOPENCL_H
#define LLVM_CLANG_SEMA_SEMAOPENCL_H

#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaOpenCL : public SemaBase {
public:
SemaOpenCL(Sema &S);

void handleNoSVMAttr(Decl *D, const ParsedAttr &AL);
void handleAccessAttr(Decl *D, const ParsedAttr &AL);

// Handles intel_reqd_sub_group_size.
void handleSubGroupSize(Decl *D, const ParsedAttr &AL);
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMAOPENCL_H
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <utility>

namespace clang {
class ParsedAttr;

class SemaOpenMP : public SemaBase {
public:
Expand Down Expand Up @@ -1348,6 +1349,8 @@ class SemaOpenMP : public SemaBase {
SourceLocation LLoc, SourceLocation RLoc,
ArrayRef<OMPIteratorData> Data);

void handleOMPAssumeAttr(Decl *D, const ParsedAttr &AL);

private:
void *VarDataSharingAttributesStack;

Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Sema/SemaRISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <memory>

namespace clang {
class ParsedAttr;

class SemaRISCV : public SemaBase {
public:
SemaRISCV(Sema &S);
Expand All @@ -36,6 +38,9 @@ class SemaRISCV : public SemaBase {

bool isValidRVVBitcast(QualType srcType, QualType destType);

void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
bool isAliasValid(unsigned BuiltinID, StringRef AliasName);

/// Indicate RISC-V vector builtin functions enabled or not.
bool DeclareRVVBuiltins = false;

Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "llvm/ADT/DenseSet.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaSYCL : public SemaBase {
public:
Expand Down Expand Up @@ -58,6 +60,8 @@ class SemaSYCL : public SemaBase {
SourceLocation LParen,
SourceLocation RParen,
ParsedType ParsedTy);

void handleKernelAttr(Decl *D, const ParsedAttr &AL);
};

} // namespace clang
Expand Down
59 changes: 59 additions & 0 deletions clang/include/clang/Sema/SemaSwift.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//===----- SemaSwift.h --- Swift language-specific routines ---*- 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
//
//===----------------------------------------------------------------------===//
/// \file
/// This file declares semantic analysis functions specific to Swift.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMASWIFT_H
#define LLVM_CLANG_SEMA_SEMASWIFT_H

#include "clang/AST/Attr.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringRef.h"

namespace clang {
class AttributeCommonInfo;
class Decl;
class ParsedAttr;
class SwiftNameAttr;

class SemaSwift : public SemaBase {
public:
SemaSwift(Sema &S);

SwiftNameAttr *mergeNameAttr(Decl *D, const SwiftNameAttr &SNA,
StringRef Name);

void handleAttrAttr(Decl *D, const ParsedAttr &AL);
void handleAsyncAttr(Decl *D, const ParsedAttr &AL);
void handleBridge(Decl *D, const ParsedAttr &AL);
void handleError(Decl *D, const ParsedAttr &AL);
void handleAsyncError(Decl *D, const ParsedAttr &AL);
void handleName(Decl *D, const ParsedAttr &AL);
void handleAsyncName(Decl *D, const ParsedAttr &AL);
void handleNewType(Decl *D, const ParsedAttr &AL);

/// Do a check to make sure \p Name looks like a legal argument for the
/// swift_name attribute applied to decl \p D. Raise a diagnostic if the name
/// is invalid for the given declaration.
///
/// \p AL is used to provide caret diagnostics in case of a malformed name.
///
/// \returns true if the name is a valid swift name for \p D, false otherwise.
bool DiagnoseName(Decl *D, StringRef Name, SourceLocation Loc,
const ParsedAttr &AL, bool IsAsync);
void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
ParameterABI abi);
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMASWIFT_H
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/SemaX86.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
#ifndef LLVM_CLANG_SEMA_SEMAX86_H
#define LLVM_CLANG_SEMA_SEMAX86_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;

class SemaX86 : public SemaBase {
public:
SemaX86(Sema &S);
Expand All @@ -32,6 +35,9 @@ class SemaX86 : public SemaBase {
ArrayRef<int> ArgNums);
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);

void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL);
void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL);
};
} // namespace clang

Expand Down
30 changes: 24 additions & 6 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ class DeclOffset {
}
};

// The unaligned decl ID used in the Blobs of bistreams.
using unaligned_decl_id_t =
llvm::support::detail::packed_endian_specific_integral<
serialization::DeclID, llvm::endianness::native,
llvm::support::unaligned>;

/// The number of predefined preprocessed entity IDs.
const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;

Expand Down Expand Up @@ -1946,6 +1952,7 @@ enum StmtCode {

// OpenACC Constructs
STMT_OPENACC_COMPUTE_CONSTRUCT,
STMT_OPENACC_LOOP_CONSTRUCT,
};

/// The kinds of designators that can occur in a
Expand Down Expand Up @@ -1979,33 +1986,44 @@ enum CleanupObjectKind { COK_Block, COK_CompoundLiteral };

/// Describes the categories of an Objective-C class.
struct ObjCCategoriesInfo {
// The ID of the definition
LocalDeclID DefinitionID;
// The ID of the definition. Use unaligned_decl_id_t to keep
// ObjCCategoriesInfo 32-bit aligned.
unaligned_decl_id_t DefinitionID;

// Offset into the array of category lists.
unsigned Offset;

ObjCCategoriesInfo() = default;
ObjCCategoriesInfo(LocalDeclID ID, unsigned Offset)
: DefinitionID(ID.get()), Offset(Offset) {}

LocalDeclID getDefinitionID() const { return LocalDeclID(DefinitionID); }

friend bool operator<(const ObjCCategoriesInfo &X,
const ObjCCategoriesInfo &Y) {
return X.DefinitionID < Y.DefinitionID;
return X.getDefinitionID() < Y.getDefinitionID();
}

friend bool operator>(const ObjCCategoriesInfo &X,
const ObjCCategoriesInfo &Y) {
return X.DefinitionID > Y.DefinitionID;
return X.getDefinitionID() > Y.getDefinitionID();
}

friend bool operator<=(const ObjCCategoriesInfo &X,
const ObjCCategoriesInfo &Y) {
return X.DefinitionID <= Y.DefinitionID;
return X.getDefinitionID() <= Y.getDefinitionID();
}

friend bool operator>=(const ObjCCategoriesInfo &X,
const ObjCCategoriesInfo &Y) {
return X.DefinitionID >= Y.DefinitionID;
return X.getDefinitionID() >= Y.getDefinitionID();
}
};

static_assert(alignof(ObjCCategoriesInfo) <= 4);
static_assert(std::is_standard_layout_v<ObjCCategoriesInfo> &&
std::is_trivial_v<ObjCCategoriesInfo>);

/// A key used when looking up entities by \ref DeclarationName.
///
/// Different \ref DeclarationNames are mapped to different keys, but the
Expand Down
41 changes: 21 additions & 20 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ class ASTReader
FileManager &FileMgr;
const PCHContainerReader &PCHContainerRdr;
DiagnosticsEngine &Diags;
// Sema has duplicate logic, but SemaObj can sometimes be null so ASTReader
// has its own version.
bool WarnedStackExhausted = false;

/// The semantic analysis object that will be processing the
/// AST files and the translation unit that uses it.
Expand Down Expand Up @@ -501,12 +504,6 @@ class ASTReader
/// = I + 1 has already been loaded.
llvm::PagedVector<Decl *> DeclsLoaded;

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<GlobalDeclID, FileOffsetsTy>;
Expand Down Expand Up @@ -589,10 +586,11 @@ class ASTReader

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

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

Expand All @@ -601,11 +599,7 @@ class ASTReader

/// An array of lexical contents of a declaration context, as a sequence of
/// Decl::Kind, DeclID pairs.
using unaligned_decl_id_t =
llvm::support::detail::packed_endian_specific_integral<
serialization::DeclID, llvm::endianness::native,
llvm::support::unaligned>;
using LexicalContents = ArrayRef<unaligned_decl_id_t>;
using LexicalContents = ArrayRef<serialization::unaligned_decl_id_t>;

/// Map from a DeclContext to its lexical contents.
llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
Expand Down Expand Up @@ -1486,22 +1480,23 @@ class ASTReader
unsigned ClientLoadCapabilities);

public:
class ModuleDeclIterator : public llvm::iterator_adaptor_base<
ModuleDeclIterator, const LocalDeclID *,
std::random_access_iterator_tag, const Decl *,
ptrdiff_t, const Decl *, const Decl *> {
class ModuleDeclIterator
: public llvm::iterator_adaptor_base<
ModuleDeclIterator, const serialization::unaligned_decl_id_t *,
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 LocalDeclID *Pos)
const serialization::unaligned_decl_id_t *Pos)
: iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {}

value_type operator*() const {
return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I));
return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, (LocalDeclID)*I));
}

value_type operator->() const { return **this; }
Expand Down Expand Up @@ -1541,6 +1536,9 @@ class ASTReader
StringRef Arg2 = StringRef(), StringRef Arg3 = StringRef()) const;
void Error(llvm::Error &&Err) const;

/// Translate a \param GlobalDeclID to the index of DeclsLoaded array.
unsigned translateGlobalDeclIDToIndex(GlobalDeclID ID) const;

public:
/// Load the AST file and validate its contents against the given
/// Preprocessor.
Expand Down Expand Up @@ -1912,7 +1910,8 @@ class ASTReader

/// 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);
ModuleFile *getOwningModuleFile(const Decl *D) const;
ModuleFile *getOwningModuleFile(GlobalDeclID ID) const;

/// Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(GlobalDeclID ID);
Expand Down Expand Up @@ -2135,6 +2134,8 @@ class ASTReader
/// Report a diagnostic.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const;

void warnStackExhausted(SourceLocation Loc);

IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID);

IdentifierInfo *readIdentifier(ModuleFile &M, const RecordData &Record,
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaConsumer.h"
Expand Down
18 changes: 3 additions & 15 deletions clang/include/clang/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,23 +454,11 @@ class ModuleFile {
/// by the declaration ID (-1).
const DeclOffset *DeclOffsets = nullptr;

/// Base declaration ID for declarations local to this module.
serialization::DeclID BaseDeclID = 0;

/// Remapping table for declaration IDs in this module.
ContinuousRangeMap<serialization::DeclID, int, 2> DeclRemap;

/// Mapping from the module files that this module file depends on
/// to the base declaration ID for that module as it is understood within this
/// module.
///
/// This is effectively a reverse global-to-local mapping for declaration
/// IDs, so that we can interpret a true global ID (for this translation unit)
/// as a local ID (for this module file).
llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
/// Base declaration index in ASTReader for declarations local to this module.
unsigned BaseDeclIndex = 0;

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

/// Array of category list location information within this
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Serialization/ModuleManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H

#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/ModuleFile.h"
#include "llvm/ADT/DenseMap.h"
Expand Down Expand Up @@ -46,7 +45,7 @@ namespace serialization {
/// Manages the set of modules loaded by an AST reader.
class ModuleManager {
/// The chain of AST files, in the order in which we started to load
/// them (this order isn't really useful for anything).
/// them.
SmallVector<std::unique_ptr<ModuleFile>, 2> Chain;

/// The chain of non-module PCH files. The first entry is the one named
Expand Down
39 changes: 30 additions & 9 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,17 @@ def CoreAlpha : Package<"core">, ParentPackage<Alpha>;
// Note: OptIn is *not* intended for checkers that are too noisy to be on by
// default. Such checkers belong in the alpha package.
def OptIn : Package<"optin">;

def CoreOptIn : Package<"core">, ParentPackage<OptIn>;

// In the Portability package reside checkers for finding code that relies on
// implementation-defined behavior. Such checks are wanted for cross-platform
// development, but unwanted for developers who target only a single platform.
def PortabilityOptIn : Package<"portability">, ParentPackage<OptIn>;

// Optional checkers related to taint security analysis.
def TaintOptIn : Package<"taint">, ParentPackage<OptIn>;

def Nullability : Package<"nullability">,
PackageOptions<[
CmdLineOption<Boolean,
Expand Down Expand Up @@ -509,6 +513,10 @@ def UnixAPIMisuseChecker : Checker<"API">,
HelpText<"Check calls to various UNIX/Posix functions">,
Documentation<HasDocumentation>;

def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
Documentation<HasDocumentation>;

def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
HelpText<"The base of several malloc() related checkers. On it's own it "
"emits no reports, but adds valuable information to the analysis "
Expand Down Expand Up @@ -619,10 +627,6 @@ def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
Documentation<HasDocumentation>;

def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
Documentation<HasDocumentation>;

} // end "alpha.unix"

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1011,6 +1015,11 @@ def FloatLoopCounter : Checker<"FloatLoopCounter">,
Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;

def PutenvStackArray : Checker<"PutenvStackArray">,
HelpText<"Finds calls to the function 'putenv' which pass a pointer to "
"an automatic (stack-allocated) array as the argument.">,
Documentation<HasDocumentation>;

def SetgidSetuidOrderChecker : Checker<"SetgidSetuidOrder">,
HelpText<"Warn on possible reversed order of 'setgid(getgid()))' and "
"'setuid(getuid())' (CERT: POS36-C)">,
Expand Down Expand Up @@ -1065,11 +1074,6 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">,
]>,
Documentation<HasDocumentation>;

def PutenvStackArray : Checker<"PutenvStackArray">,
HelpText<"Finds calls to the function 'putenv' which pass a pointer to "
"an automatic (stack-allocated) array as the argument.">,
Documentation<HasDocumentation>;

def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
HelpText<"Check for an out-of-bound pointer being returned to callers">,
Documentation<HasDocumentation>;
Expand Down Expand Up @@ -1718,6 +1722,23 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">,

} // end optin.portability


//===----------------------------------------------------------------------===//
// Taint checkers.
//===----------------------------------------------------------------------===//

let ParentPackage = TaintOptIn in {

def TaintedAllocChecker: Checker<"TaintedAlloc">,
HelpText<"Check for memory allocations, where the size parameter "
"might be a tainted (attacker controlled) value.">,
Dependencies<[DynamicMemoryModeling]>,
//FIXME: GenericTaintChecker should be a dependency, but only after it
//is transformed into a modeling checker
Documentation<HasDocumentation>;

} // end "optin.taint"

//===----------------------------------------------------------------------===//
// NonDeterminism checkers.
//===----------------------------------------------------------------------===//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H

#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/Utils.h"
Expand Down Expand Up @@ -138,6 +139,10 @@ struct ModuleDeps {
/// determined that the differences are benign for this compilation.
std::vector<ModuleID> ClangModuleDeps;

/// The set of libraries or frameworks to link against when
/// an entity from this module is used.
llvm::SmallVector<Module::LinkLibrary, 2> LinkLibraries;

/// Get (or compute) the compiler invocation that can be used to build this
/// module. Does not include argv[0].
const std::vector<std::string> &getBuildArguments();
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Tooling/Syntax/Tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,9 @@ class TokenBuffer {
/// "DECL", "(", "a", ")", ";"}
llvm::ArrayRef<syntax::Token> spelledTokens(FileID FID) const;

/// Returns the spelled Token starting at Loc, if there are no such tokens
/// Returns the spelled Token containing the Loc, if there are no such tokens
/// returns nullptr.
const syntax::Token *spelledTokenAt(SourceLocation Loc) const;
const syntax::Token *spelledTokenContaining(SourceLocation Loc) const;

/// Get all tokens that expand a macro in \p FID. For the following input
/// #define FOO B
Expand Down
1 change: 1 addition & 0 deletions clang/lib/APINotes/APINotesManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceMgrAdapter.h"
#include "clang/Basic/Version.h"
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12018,7 +12018,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return false;

// Variables in other module units shouldn't be forced to be emitted.
if (VD->isInAnotherModuleUnit())
if (VD->shouldEmitInExternalSource())
return false;

// Variables that can be needed in other TUs are required.
Expand Down
1 change: 0 additions & 1 deletion clang/lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "clang/AST/DeclLookups.h"
#include "clang/AST/JSONNodeDumper.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2929,7 +2929,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {

// We may already have an enum of the same name; try to find and match it.
EnumDecl *PrevDecl = nullptr;
if (!DC->isFunctionOrMethod() && SearchName) {
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
auto FoundDecls =
Importer.findDeclsInToCtx(DC, SearchName);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ add_clang_library(clangAST
Interp/Record.cpp
Interp/Source.cpp
Interp/State.cpp
Interp/MemberPointer.cpp
Interp/InterpShared.cpp
ItaniumCXXABI.cpp
ItaniumMangle.cpp
Expand Down
11 changes: 2 additions & 9 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,13 +1174,6 @@ Linkage NamedDecl::getLinkageInternal() const {
.getLinkage();
}

/// Determine whether D is attached to a named module.
static bool isInNamedModule(const NamedDecl *D) {
if (auto *M = D->getOwningModule())
return M->isNamedModule();
return false;
}

static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
// FIXME: Handle isModulePrivate.
switch (D->getModuleOwnershipKind()) {
Expand All @@ -1190,7 +1183,7 @@ static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
return false;
case Decl::ModuleOwnershipKind::Visible:
case Decl::ModuleOwnershipKind::VisibleWhenImported:
return isInNamedModule(D);
return D->isInNamedModule();
}
llvm_unreachable("unexpected module ownership kind");
}
Expand All @@ -1208,7 +1201,7 @@ Linkage NamedDecl::getFormalLinkage() const {
// [basic.namespace.general]/p2
// A namespace is never attached to a named module and never has a name with
// module linkage.
if (isInNamedModule(this) && InternalLinkage == Linkage::External &&
if (isInNamedModule() && InternalLinkage == Linkage::External &&
!isExportedFromModuleInterfaceUnit(
cast<NamedDecl>(this->getCanonicalDecl())) &&
!isa<NamespaceDecl>(this))
Expand Down
Loading