55 changes: 46 additions & 9 deletions clang/include/clang/AST/StmtOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#ifndef LLVM_CLANG_AST_STMTOPENACC_H
#define LLVM_CLANG_AST_STMTOPENACC_H

#include "clang/AST/OpenACCClause.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/SourceLocation.h"
#include <memory>

namespace clang {
/// This is the base class for an OpenACC statement-level construct, other
Expand All @@ -30,13 +32,23 @@ class OpenACCConstructStmt : public Stmt {
/// the directive.
SourceRange Range;

// TODO OPENACC: Clauses should probably be collected in this class.
/// The list of clauses. This is stored here as an ArrayRef, as this is the
/// most convienient place to access the list, however the list itself should
/// be stored in leaf nodes, likely in trailing-storage.
MutableArrayRef<const OpenACCClause *> Clauses;

protected:
OpenACCConstructStmt(StmtClass SC, OpenACCDirectiveKind K,
SourceLocation Start, SourceLocation End)
: Stmt(SC), Kind(K), Range(Start, End) {}

// Used only for initialization, the leaf class can initialize this to
// trailing storage.
void setClauseList(MutableArrayRef<const OpenACCClause *> NewClauses) {
assert(Clauses.empty() && "Cannot change clause list");
Clauses = NewClauses;
}

public:
OpenACCDirectiveKind getDirectiveKind() const { return Kind; }

Expand All @@ -47,6 +59,7 @@ class OpenACCConstructStmt : public Stmt {

SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
ArrayRef<const OpenACCClause *> clauses() const { return Clauses; }

child_range children() {
return child_range(child_iterator(), child_iterator());
Expand Down Expand Up @@ -101,24 +114,46 @@ class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt {
/// those three, as they are semantically identical, and have only minor
/// differences in the permitted list of clauses, which can be differentiated by
/// the 'Kind'.
class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct {
class OpenACCComputeConstruct final
: public OpenACCAssociatedStmtConstruct,
public llvm::TrailingObjects<OpenACCComputeConstruct,
const OpenACCClause *> {
friend class ASTStmtWriter;
friend class ASTStmtReader;
friend class ASTContext;
OpenACCComputeConstruct()
: OpenACCAssociatedStmtConstruct(
OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid,
SourceLocation{}, SourceLocation{}, /*AssociatedStmt=*/nullptr) {}
OpenACCComputeConstruct(unsigned NumClauses)
: OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass,
OpenACCDirectiveKind::Invalid,
SourceLocation{}, SourceLocation{},
/*AssociatedStmt=*/nullptr) {
// We cannot send the TrailingObjects storage to the base class (which holds
// a reference to the data) until it is constructed, so we have to set it
// separately here.
std::uninitialized_value_construct(
getTrailingObjects<const OpenACCClause *>(),
getTrailingObjects<const OpenACCClause *>() + NumClauses);
setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
NumClauses));
}

OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start,
SourceLocation End, Stmt *StructuredBlock)
SourceLocation End,
ArrayRef<const OpenACCClause *> Clauses,
Stmt *StructuredBlock)
: OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, K, Start,
End, StructuredBlock) {
assert((K == OpenACCDirectiveKind::Parallel ||
K == OpenACCDirectiveKind::Serial ||
K == OpenACCDirectiveKind::Kernels) &&
"Only parallel, serial, and kernels constructs should be "
"represented by this type");

// Initialize the trailing storage.
std::uninitialized_copy(Clauses.begin(), Clauses.end(),
getTrailingObjects<const OpenACCClause *>());

setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
Clauses.size()));
}

void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
Expand All @@ -128,10 +163,12 @@ class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct {
return T->getStmtClass() == OpenACCComputeConstructClass;
}

static OpenACCComputeConstruct *CreateEmpty(const ASTContext &C, EmptyShell);
static OpenACCComputeConstruct *CreateEmpty(const ASTContext &C,
unsigned NumClauses);
static OpenACCComputeConstruct *
Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
SourceLocation EndLoc, Stmt *StructuredBlock);
SourceLocation EndLoc, ArrayRef<const OpenACCClause *> Clauses,
Stmt *StructuredBlock);

Stmt *getStructuredBlock() { return getAssociatedStmt(); }
const Stmt *getStructuredBlock() const {
Expand Down
11 changes: 10 additions & 1 deletion clang/include/clang/AST/StmtOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -6109,6 +6109,8 @@ class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
/// true if loop directive's associated loop can be a parallel for.
bool CanBeParallelFor = false;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
Expand All @@ -6131,6 +6133,9 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
llvm::omp::OMPD_target_teams_loop, SourceLocation(),
SourceLocation(), CollapsedNum) {}

/// Set whether associated loop can be a parallel for.
void setCanBeParallelFor(bool ParFor) { CanBeParallelFor = ParFor; }

public:
/// Creates directive with a list of \p Clauses.
///
Expand All @@ -6145,7 +6150,7 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
static OMPTargetTeamsGenericLoopDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool CanBeParallelFor);

/// Creates an empty directive with the place
/// for \a NumClauses clauses.
Expand All @@ -6159,6 +6164,10 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
unsigned CollapsedNum,
EmptyShell);

/// Return true if current loop directive's associated loop can be a
/// parallel for.
bool canBeParallelFor() const { return CanBeParallelFor; }

static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
}
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ class TextNodeDumper

void Visit(const OMPClause *C);

void Visit(const OpenACCClause *C);

void Visit(const BlockDecl::Capture &C);

void Visit(const GenericSelectionExpr::ConstAssociation &A);
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4961,6 +4961,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher<LambdaCapture>,
/// capturesVar(hasName("x")) matches `x` and `x = 1`.
AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher<ValueDecl>,
InnerMatcher) {
if (!Node.capturesVariable())
return false;
auto *capturedVar = Node.getCapturedVar();
return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
}
Expand Down
27 changes: 0 additions & 27 deletions clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h

This file was deleted.

64 changes: 44 additions & 20 deletions clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <memory>
#include <type_traits>
#include <utility>

Expand Down Expand Up @@ -344,17 +345,6 @@ class Environment {
/// location of the result object to pass in `this`, even though prvalues are
/// otherwise not associated with storage locations.
///
/// FIXME: Currently, this simply returns a stable storage location for `E`,
/// but this doesn't do the right thing in scenarios like the following:
/// ```
/// MyClass c = some_condition()? MyClass(foo) : MyClass(bar);
/// ```
/// Here, `MyClass(foo)` and `MyClass(bar)` will have two different storage
/// locations, when in fact their storage locations should be the same.
/// Eventually, we want to propagate storage locations from result objects
/// down to the prvalues that initialize them, similar to the way that this is
/// done in Clang's CodeGen.
///
/// Requirements:
/// `E` must be a prvalue of record type.
RecordStorageLocation &
Expand Down Expand Up @@ -462,7 +452,13 @@ class Environment {
/// Initializes the fields (including synthetic fields) of `Loc` with values,
/// unless values of the field type are not supported or we hit one of the
/// limits at which we stop producing values.
void initializeFieldsWithValues(RecordStorageLocation &Loc);
/// If `Type` is provided, initializes only those fields that are modeled for
/// `Type`; this is intended for use in cases where `Loc` is a derived type
/// and we only want to initialize the fields of a base type.
void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type);
void initializeFieldsWithValues(RecordStorageLocation &Loc) {
initializeFieldsWithValues(Loc, Loc.getType());
}

/// Assigns `Val` as the value of `Loc` in the environment.
void setValue(const StorageLocation &Loc, Value &Val);
Expand Down Expand Up @@ -653,6 +649,9 @@ class Environment {
LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;

private:
using PrValueToResultObject =
llvm::DenseMap<const Expr *, RecordStorageLocation *>;

// The copy-constructor is for use in fork() only.
Environment(const Environment &) = default;

Expand Down Expand Up @@ -682,8 +681,10 @@ class Environment {
/// Initializes the fields (including synthetic fields) of `Loc` with values,
/// unless values of the field type are not supported or we hit one of the
/// limits at which we stop producing values (controlled by `Visited`,
/// `Depth`, and `CreatedValuesCount`).
void initializeFieldsWithValues(RecordStorageLocation &Loc,
/// `Depth`, and `CreatedValuesCount`). If `Type` is different from
/// `Loc.getType()`, initializes only those fields that are modeled for
/// `Type`.
void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type,
llvm::DenseSet<QualType> &Visited, int Depth,
int &CreatedValuesCount);

Expand All @@ -702,22 +703,45 @@ class Environment {
/// and functions referenced in `FuncDecl`. `FuncDecl` must have a body.
void initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl);

static PrValueToResultObject
buildResultObjectMap(DataflowAnalysisContext *DACtx,
const FunctionDecl *FuncDecl,
RecordStorageLocation *ThisPointeeLoc,
RecordStorageLocation *LocForRecordReturnVal);

// `DACtx` is not null and not owned by this object.
DataflowAnalysisContext *DACtx;

// FIXME: move the fields `CallStack`, `ReturnVal`, `ReturnLoc` and
// `ThisPointeeLoc` into a separate call-context object, shared between
// environments in the same call.
// FIXME: move the fields `CallStack`, `ResultObjectMap`, `ReturnVal`,
// `ReturnLoc` and `ThisPointeeLoc` into a separate call-context object,
// shared between environments in the same call.
// https://github.com/llvm/llvm-project/issues/59005

// `DeclContext` of the block being analysed if provided.
std::vector<const DeclContext *> CallStack;

// Value returned by the function (if it has non-reference return type).
// Maps from prvalues of record type to their result objects. Shared between
// all environments for the same function.
// FIXME: It's somewhat unsatisfactory that we have to use a `shared_ptr`
// here, though the cost is acceptable: The overhead of a `shared_ptr` is
// incurred when it is copied, and this happens only relatively rarely (when
// we fork the environment). The need for a `shared_ptr` will go away once we
// introduce a shared call-context object (see above).
std::shared_ptr<PrValueToResultObject> ResultObjectMap;

// The following three member variables handle various different types of
// return values.
// - If the return type is not a reference and not a record: Value returned
// by the function.
Value *ReturnVal = nullptr;
// Storage location of the reference returned by the function (if it has
// reference return type).
// - If the return type is a reference: Storage location of the reference
// returned by the function.
StorageLocation *ReturnLoc = nullptr;
// - If the return type is a record or the function being analyzed is a
// constructor: Storage location into which the return value should be
// constructed.
RecordStorageLocation *LocForRecordReturnVal = nullptr;

// The storage location of the `this` pointee. Should only be null if the
// function being analyzed is only a function and not a method.
RecordStorageLocation *ThisPointeeLoc = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Analysis/SelectorExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ namespace clang {

template <typename... IdentifierInfos>
static inline Selector getKeywordSelector(ASTContext &Ctx,
IdentifierInfos *... IIs) {
const IdentifierInfos *...IIs) {
static_assert(sizeof...(IdentifierInfos) > 0,
"keyword selectors must have at least one argument");
SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});
SmallVector<const IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});

return Ctx.Selectors.getSelector(II.size(), &II[0]);
}
Expand Down
14 changes: 1 addition & 13 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,10 @@ class Spelling<string name, string variety, int version = 1> {
}

class GNU<string name> : Spelling<name, "GNU">;
class Declspec<string name> : Spelling<name, "Declspec"> {
bit PrintOnLeft = 1;
}
class Declspec<string name> : Spelling<name, "Declspec">;
class Microsoft<string name> : Spelling<name, "Microsoft">;
class CXX11<string namespace, string name, int version = 1>
: Spelling<name, "CXX11", version> {
bit CanPrintOnLeft = 0;
string Namespace = namespace;
}
class C23<string namespace, string name, int version = 1>
Expand Down Expand Up @@ -596,12 +593,6 @@ class AttrSubjectMatcherAggregateRule<AttrSubject subject> {
def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule<Named>;

class Attr {
// Specifies that when printed, this attribute is meaningful on the
// 'left side' of the declaration.
bit CanPrintOnLeft = 1;
// Specifies that when printed, this attribute is required to be printed on
// the 'left side' of the declaration.
bit PrintOnLeft = 0;
// The various ways in which an attribute can be spelled in source
list<Spelling> Spellings;
// The things to which an attribute can appertain
Expand Down Expand Up @@ -937,7 +928,6 @@ def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
}

def AsmLabel : InheritableAttr {
let CanPrintOnLeft = 0;
let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
let Args = [
// Label specifies the mangled name for the decl.
Expand Down Expand Up @@ -1534,7 +1524,6 @@ def AllocSize : InheritableAttr {
}

def EnableIf : InheritableAttr {
let CanPrintOnLeft = 0;
// Does not have a [[]] spelling because this attribute requires the ability
// to parse function arguments but the attribute is not written in the type
// position.
Expand Down Expand Up @@ -3171,7 +3160,6 @@ def Unavailable : InheritableAttr {
}

def DiagnoseIf : InheritableAttr {
let CanPrintOnLeft = 0;
// Does not have a [[]] spelling because this attribute requires the ability
// to parse function arguments but the attribute is not written in the type
// position.
Expand Down
10 changes: 0 additions & 10 deletions clang/include/clang/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,6 @@ clang_tablegen(AttrList.inc -gen-clang-attr-list
SOURCE Attr.td
TARGET ClangAttrList)

clang_tablegen(AttrLeftSideCanPrintList.inc -gen-clang-attr-can-print-left-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE Attr.td
TARGET ClangAttrCanPrintLeftList)

clang_tablegen(AttrLeftSideMustPrintList.inc -gen-clang-attr-must-print-left-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE Attr.td
TARGET ClangAttrMustPrintLeftList)

clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE Attr.td
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ def warn_drv_darwin_sdk_invalid_settings : Warning<
"SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
InGroup<DiagGroup<"darwin-sdk-settings">>;

def err_missing_sysroot : Error<"no such sysroot directory: '%0'">;
def err_drv_darwin_sdk_missing_arclite : Error<
"SDK does not contain 'libarclite' at the path '%0'; try increasing the minimum deployment target">;

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,9 @@ def MultiGPU: DiagGroup<"multi-gpu">;
// libc and the CRT to be skipped.
def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">;

// A warning group related to AArch64 SME function attribues.
def AArch64SMEAttributes : DiagGroup<"aarch64-sme-attributes">;

// A warning group for things that will change semantics in the future.
def FutureCompat : DiagGroup<"future-compat">;

Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ def err_no_such_header_file : Error<"no such %select{public|private|project}1 he
def warn_no_such_excluded_header_file : Warning<"no such excluded %select{public|private}0 header file: '%1'">, InGroup<InstallAPIViolation>;
def warn_glob_did_not_match: Warning<"glob '%0' did not match any header file">, InGroup<InstallAPIViolation>;
def err_no_such_umbrella_header_file : Error<"%select{public|private|project}1 umbrella header file not found in input: '%0'">;
def err_cannot_find_reexport : Error<"cannot find re-exported %select{framework|library}0: '%1'">;
} // end of command line category.

let CategoryName = "Verification" in {
// Diagnostics about symbols.
def warn_target: Warning<"violations found for %0">, InGroup<InstallAPIViolation>;
def err_library_missing_symbol : Error<"declaration has external linkage, but dynamic library doesn't have symbol '%0'">;
def warn_library_missing_symbol : Warning<"declaration has external linkage, but dynamic library doesn't have symbol '%0'">, InGroup<InstallAPIViolation>;
Expand All @@ -43,6 +45,25 @@ def err_dylib_symbol_flags_mismatch : Error<"dynamic library symbol '%0' is "
"%select{weak defined|thread local}1, but its declaration is not">;
def err_header_symbol_flags_mismatch : Error<"declaration '%0' is "
"%select{weak defined|thread local}1, but symbol is not in dynamic library">;

// Diagnostics about load commands.
def err_architecture_mismatch : Error<"architectures do not match: '%0' (provided) vs '%1' (found)">;
def warn_platform_mismatch : Warning<"platform does not match: '%0' (provided) vs '%1' (found)">, InGroup<InstallAPIViolation>;
def err_platform_mismatch : Error<"platform does not match: '%0' (provided) vs '%1' (found)">;
def err_install_name_mismatch : Error<"install_name does not match: '%0' (provided) vs '%1' (found)">;
def err_current_version_mismatch : Error<"current_version does not match: '%0' (provided) vs '%1' (found)">;
def err_compatibility_version_mismatch : Error<"compatibility_version does not match: '%0' (provided) vs '%1' (found)">;
def err_appextension_safe_mismatch : Error<"ApplicationExtensionSafe flag does not match: '%0' (provided) vs '%1' (found)">;
def err_shared_cache_eligiblity_mismatch : Error<"NotForDyldSharedCache flag does not match: '%0' (provided) vs '%1' (found)">;
def err_no_twolevel_namespace : Error<"flat namespace libraries are not supported">;
def err_parent_umbrella_missing: Error<"parent umbrella missing from %0: '%1'">;
def err_parent_umbrella_mismatch : Error<"parent umbrella does not match: '%0' (provided) vs '%1' (found)">;
def err_reexported_libraries_missing : Error<"re-exported library missing from %0: '%1'">;
def err_reexported_libraries_mismatch : Error<"re-exported libraries do not match: '%0' (provided) vs '%1' (found)">;
def err_allowable_clients_missing : Error<"allowable client missing from %0: '%1'">;
def err_allowable_clients_mismatch : Error<"allowable clients do not match: '%0' (provided) vs '%1' (found)">;
def warn_rpaths_missing : Warning<"runpath search paths missing from %0: '%1'">, InGroup<InstallAPIViolation>;
def warn_rpaths_mismatch : Warning<"runpath search paths do not match: '%0' (provided) vs '%1' (found)">, InGroup<InstallAPIViolation>;
} // end of Verification category.

} // end of InstallAPI component
28 changes: 22 additions & 6 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def ext_vla_folded_to_constant : ExtWarn<
"variable length array folded to constant array as an extension">,
InGroup<GNUFoldingConstant>;
def err_vla_unsupported : Error<
"variable length arrays are not supported for %select{the current target|'%1'}0">;
"variable length arrays are not supported %select{for the current target|in '%1'}0">;
def err_vla_in_coroutine_unsupported : Error<
"variable length arrays in a coroutine are not supported">;
def note_vla_unsupported : Note<
Expand Down Expand Up @@ -2402,10 +2402,6 @@ def err_selected_explicit_constructor : Error<
def note_explicit_ctor_deduction_guide_here : Note<
"explicit %select{constructor|deduction guide}0 declared here">;

// C++11 decltype
def err_decltype_in_declarator : Error<
"'decltype' cannot be used to name a declaration">;

// C++11 auto
def warn_cxx98_compat_auto_type_specifier : Warning<
"'auto' type specifier is incompatible with C++98">,
Expand Down Expand Up @@ -3755,6 +3751,16 @@ def err_sme_definition_using_za_in_non_sme_target : Error<
"function using ZA state requires 'sme'">;
def err_sme_definition_using_zt0_in_non_sme2_target : Error<
"function using ZT0 state requires 'sme2'">;
def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
"passing a VL-dependent argument to/from a function that has a different"
" streaming-mode. The streaming and non-streaming vector lengths may be"
" different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
"passing/returning a VL-dependent argument to/from a __arm_locally_streaming"
" function. The streaming and non-streaming vector"
" lengths may be different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
def err_sme_streaming_cannot_be_multiversioned : Error<
Expand Down Expand Up @@ -7142,7 +7148,8 @@ def ext_typecheck_decl_incomplete_type : ExtWarn<
def err_tentative_def_incomplete_type : Error<
"tentative definition has type %0 that is never completed">;
def warn_tentative_incomplete_array : Warning<
"tentative array definition assumed to have one element">;
"tentative array definition assumed to have one element">,
InGroup<DiagGroup<"tentative-definition-array">>;
def err_typecheck_incomplete_array_needs_initializer : Error<
"definition of variable with array type needs an explicit size "
"or an initializer">;
Expand Down Expand Up @@ -8302,6 +8309,9 @@ def ext_template_after_declarative_nns : ExtWarn<
def ext_alias_template_in_declarative_nns : ExtWarn<
"a declarative nested name specifier cannot name an alias template">,
InGroup<DiagGroup<"alias-template-in-declaration-name">>;
def err_computed_type_in_declarative_nns : Error<
"a %select{pack indexing|'decltype'}0 specifier cannot be used in "
"a declarative nested name specifier">;

def err_no_typeid_with_fno_rtti : Error<
"use of typeid requires -frtti">;
Expand Down Expand Up @@ -12252,6 +12262,12 @@ def warn_acc_clause_unimplemented
def err_acc_construct_appertainment
: Error<"OpenACC construct '%0' cannot be used here; it can only "
"be used in a statement context">;
def err_acc_clause_appertainment
: Error<"OpenACC '%1' clause is not valid on '%0' directive">;
def err_acc_duplicate_clause_disallowed
: Error<"OpenACC '%1' clause cannot appear more than once on a '%0' "
"directive">;
def note_acc_previous_clause_here : Note<"previous clause is here">;
def err_acc_branch_in_out_compute_construct
: Error<"invalid %select{branch|return|throw}0 %select{out of|into}1 "
"OpenACC Compute Construct">;
Expand Down
25 changes: 13 additions & 12 deletions clang/include/clang/Basic/IdentifierTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -913,12 +913,13 @@ class alignas(IdentifierInfoAlignment) MultiKeywordSelector

public:
// Constructor for keyword selectors.
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
MultiKeywordSelector(unsigned nKeys, const IdentifierInfo **IIV)
: DeclarationNameExtra(nKeys) {
assert((nKeys > 1) && "not a multi-keyword selector");

// Fill in the trailing keyword array.
IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this + 1);
const IdentifierInfo **KeyInfo =
reinterpret_cast<const IdentifierInfo **>(this + 1);
for (unsigned i = 0; i != nKeys; ++i)
KeyInfo[i] = IIV[i];
}
Expand All @@ -928,7 +929,7 @@ class alignas(IdentifierInfoAlignment) MultiKeywordSelector

using DeclarationNameExtra::getNumArgs;

using keyword_iterator = IdentifierInfo *const *;
using keyword_iterator = const IdentifierInfo *const *;

keyword_iterator keyword_begin() const {
return reinterpret_cast<keyword_iterator>(this + 1);
Expand All @@ -938,7 +939,7 @@ class alignas(IdentifierInfoAlignment) MultiKeywordSelector
return keyword_begin() + getNumArgs();
}

IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
const IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
return keyword_begin()[i];
}
Expand Down Expand Up @@ -991,10 +992,10 @@ class Selector {
/// Do not reorder or add any arguments to this template
/// without thoroughly understanding how tightly coupled these classes are.
llvm::PointerIntPair<
llvm::PointerUnion<IdentifierInfo *, MultiKeywordSelector *>, 2>
llvm::PointerUnion<const IdentifierInfo *, MultiKeywordSelector *>, 2>
InfoPtr;

Selector(IdentifierInfo *II, unsigned nArgs) {
Selector(const IdentifierInfo *II, unsigned nArgs) {
assert(nArgs < 2 && "nArgs not equal to 0/1");
InfoPtr.setPointerAndInt(II, nArgs + 1);
}
Expand All @@ -1006,8 +1007,8 @@ class Selector {
InfoPtr.setPointerAndInt(SI, MultiArg & 0b11);
}

IdentifierInfo *getAsIdentifierInfo() const {
return InfoPtr.getPointer().dyn_cast<IdentifierInfo *>();
const IdentifierInfo *getAsIdentifierInfo() const {
return InfoPtr.getPointer().dyn_cast<const IdentifierInfo *>();
}

MultiKeywordSelector *getMultiKeywordSelector() const {
Expand Down Expand Up @@ -1075,7 +1076,7 @@ class Selector {
///
/// \returns the uniqued identifier for this slot, or NULL if this slot has
/// no corresponding identifier.
IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
const IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;

/// Retrieve the name at a given position in the selector.
///
Expand Down Expand Up @@ -1132,13 +1133,13 @@ class SelectorTable {
///
/// \p NumArgs indicates whether this is a no argument selector "foo", a
/// single argument selector "foo:" or multi-argument "foo:bar:".
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV);

Selector getUnarySelector(IdentifierInfo *ID) {
Selector getUnarySelector(const IdentifierInfo *ID) {
return Selector(ID, 1);
}

Selector getNullarySelector(IdentifierInfo *ID) {
Selector getNullarySelector(const IdentifierInfo *ID) {
return Selector(ID, 0);
}

Expand Down
36 changes: 30 additions & 6 deletions clang/include/clang/Basic/OpenACCKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ enum class OpenACCDirectiveKind {
};

template <typename StreamTy>
inline StreamTy &PrintOpenACCDirectiveKind(StreamTy &Out,
inline StreamTy &printOpenACCDirectiveKind(StreamTy &Out,
OpenACCDirectiveKind K) {
switch (K) {
case OpenACCDirectiveKind::Parallel:
Expand Down Expand Up @@ -138,12 +138,12 @@ inline StreamTy &PrintOpenACCDirectiveKind(StreamTy &Out,

inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
OpenACCDirectiveKind K) {
return PrintOpenACCDirectiveKind(Out, K);
return printOpenACCDirectiveKind(Out, K);
}

inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
OpenACCDirectiveKind K) {
return PrintOpenACCDirectiveKind(Out, K);
return printOpenACCDirectiveKind(Out, K);
}

enum class OpenACCAtomicKind {
Expand Down Expand Up @@ -266,7 +266,7 @@ enum class OpenACCClauseKind {
};

template <typename StreamTy>
inline StreamTy &PrintOpenACCClauseKind(StreamTy &Out, OpenACCClauseKind K) {
inline StreamTy &printOpenACCClauseKind(StreamTy &Out, OpenACCClauseKind K) {
switch (K) {
case OpenACCClauseKind::Finalize:
return Out << "finalize";
Expand Down Expand Up @@ -402,12 +402,12 @@ inline StreamTy &PrintOpenACCClauseKind(StreamTy &Out, OpenACCClauseKind K) {

inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
OpenACCClauseKind K) {
return PrintOpenACCClauseKind(Out, K);
return printOpenACCClauseKind(Out, K);
}

inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
OpenACCClauseKind K) {
return PrintOpenACCClauseKind(Out, K);
return printOpenACCClauseKind(Out, K);
}

enum class OpenACCDefaultClauseKind {
Expand All @@ -419,6 +419,30 @@ enum class OpenACCDefaultClauseKind {
Invalid,
};

template <typename StreamTy>
inline StreamTy &printOpenACCDefaultClauseKind(StreamTy &Out,
OpenACCDefaultClauseKind K) {
switch (K) {
case OpenACCDefaultClauseKind::None:
return Out << "none";
case OpenACCDefaultClauseKind::Present:
return Out << "present";
case OpenACCDefaultClauseKind::Invalid:
return Out << "<invalid>";
}
llvm_unreachable("Unknown OpenACCDefaultClauseKind enum");
}

inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
OpenACCDefaultClauseKind K) {
return printOpenACCDefaultClauseKind(Out, K);
}

inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
OpenACCDefaultClauseKind K) {
return printOpenACCDefaultClauseKind(Out, K);
}

enum class OpenACCReductionOperator {
/// '+'.
Addition,
Expand Down
20 changes: 10 additions & 10 deletions clang/include/clang/Basic/Sanitizers.def
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,24 @@ SANITIZER_GROUP("implicit-integer-arithmetic-value-change",
ImplicitIntegerArithmeticValueChange,
ImplicitIntegerSignChange | ImplicitSignedIntegerTruncation)

SANITIZER("objc-cast", ObjCCast)
SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
ImplicitIntegerArithmeticValueChange |
ImplicitUnsignedIntegerTruncation)

// FIXME:
//SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
// ImplicitIntegerArithmeticValueChange |
// ImplicitUnsignedIntegerTruncation)
//SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
// ImplicitIntegerConversion)
// Implicit bitfield sanitizers
SANITIZER("implicit-bitfield-conversion", ImplicitBitfieldConversion)

SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
ImplicitIntegerArithmeticValueChange |
ImplicitUnsignedIntegerTruncation)
ImplicitIntegerConversion |
ImplicitBitfieldConversion)

SANITIZER_GROUP("integer", Integer,
ImplicitConversion | IntegerDivideByZero | Shift |
ImplicitIntegerConversion | IntegerDivideByZero | Shift |
SignedIntegerOverflow | UnsignedIntegerOverflow |
UnsignedShiftBase)

SANITIZER("objc-cast", ObjCCast)

SANITIZER("local-bounds", LocalBounds)
SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)

Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,8 @@ def : Joined<["-"], "Xclang=">, Group<CompileOnly_Group>,
def Xcuda_fatbinary : Separate<["-"], "Xcuda-fatbinary">,
HelpText<"Pass <arg> to fatbinary invocation">, MetaVarName<"<arg>">;
def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">,
HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">;
HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">,
Visibility<[ClangOption, CLOption]>;
def Xopenmp_target : Separate<["-"], "Xopenmp-target">, Group<CompileOnly_Group>,
HelpText<"Pass <arg> to the target offloading toolchain.">, MetaVarName<"<arg>">;
def Xopenmp_target_EQ : JoinedAndSeparate<["-"], "Xopenmp-target=">, Group<CompileOnly_Group>,
Expand Down Expand Up @@ -1448,7 +1449,7 @@ def dD : Flag<["-"], "dD">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>
def dI : Flag<["-"], "dI">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print include directives in -E mode in addition to normal output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowIncludeDirectives">>;
def dM : Flag<["-"], "dM">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
def dM : Flag<["-"], "dM">, Group<d_Group>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Print macro definitions in -E mode instead of normal output">;
def dead__strip : Flag<["-"], "dead_strip">;
def dependency_file : Separate<["-"], "dependency-file">,
Expand Down Expand Up @@ -4911,6 +4912,9 @@ defm tgsplit : SimpleMFlag<"tgsplit", "Enable", "Disable",
defm wavefrontsize64 : SimpleMFlag<"wavefrontsize64",
"Specify wavefront size 64", "Specify wavefront size 32",
" mode (AMDGPU only)">;
defm amdgpu_precise_memory_op
: SimpleMFlag<"amdgpu-precise-memory-op", "Enable", "Disable",
" precise memory mode (AMDGPU only)">;

defm unsafe_fp_atomics : BoolMOption<"unsafe-fp-atomics",
TargetOpts<"AllowAMDGPUUnsafeFPAtomics">, DefaultFalse,
Expand Down
14 changes: 2 additions & 12 deletions clang/include/clang/Frontend/FrontendActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,12 @@ class InitOnlyAction : public FrontendAction {

/// Preprocessor-based frontend action that also loads PCH files.
class ReadPCHAndPreprocessAction : public FrontendAction {
llvm::unique_function<void(CompilerInstance &)> AdjustCI;

void ExecuteAction() override;

std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;

public:
ReadPCHAndPreprocessAction(
llvm::unique_function<void(CompilerInstance &)> AdjustCI)
: AdjustCI(std::move(AdjustCI)) {}

bool usesPreprocessorOnly() const override { return false; }
};

Expand Down Expand Up @@ -327,15 +321,11 @@ class PrintPreprocessedAction : public PreprocessorFrontendAction {

class GetDependenciesByModuleNameAction : public PreprocessOnlyAction {
StringRef ModuleName;
llvm::unique_function<void(CompilerInstance &)> AdjustCI;

void ExecuteAction() override;

public:
GetDependenciesByModuleNameAction(
StringRef ModuleName,
llvm::unique_function<void(CompilerInstance &)> AdjustCI)
: ModuleName(ModuleName), AdjustCI(std::move(AdjustCI)) {}
GetDependenciesByModuleNameAction(StringRef ModuleName)
: ModuleName(ModuleName) {}
};

} // end namespace clang
Expand Down
17 changes: 17 additions & 0 deletions clang/include/clang/InstallAPI/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ struct InstallAPIContext {
/// Library attributes that are typically passed as linker inputs.
BinaryAttrs BA;

/// Install names of reexported libraries of a library.
LibAttrs Reexports;

/// All headers that represent a library.
HeaderSeq InputHeaders;

Expand Down Expand Up @@ -80,6 +83,20 @@ struct InstallAPIContext {
llvm::DenseMap<StringRef, HeaderType> KnownIncludes;
};

/// Lookup the dylib or TextAPI file location for a system library or framework.
/// The search paths provided are searched in order.
/// @rpath based libraries are not supported.
///
/// \param InstallName The install name for the library.
/// \param FrameworkSearchPaths Search paths to look up frameworks with.
/// \param LibrarySearchPaths Search paths to look up dylibs with.
/// \param SearchPaths Fallback search paths if library was not found in earlier
/// paths.
/// \return The full path of the library.
std::string findLibrary(StringRef InstallName, FileManager &FM,
ArrayRef<std::string> FrameworkSearchPaths,
ArrayRef<std::string> LibrarySearchPaths,
ArrayRef<std::string> SearchPaths);
} // namespace installapi
} // namespace clang

Expand Down
39 changes: 29 additions & 10 deletions clang/include/clang/InstallAPI/DylibVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/InstallAPI/MachO.h"

namespace clang {
Expand All @@ -24,6 +25,9 @@ enum class VerificationMode {
Pedantic,
};

using LibAttrs = llvm::StringMap<ArchitectureSet>;
using ReexportedInterfaces = llvm::SmallVector<llvm::MachO::InterfaceFile, 8>;

/// Service responsible to tracking state of verification across the
/// lifetime of InstallAPI.
/// As declarations are collected during AST traversal, they are
Expand Down Expand Up @@ -63,11 +67,12 @@ class DylibVerifier : llvm::MachO::RecordVisitor {

DylibVerifier() = default;

DylibVerifier(llvm::MachO::Records &&Dylib, DiagnosticsEngine *Diag,
VerificationMode Mode, bool Demangle, StringRef DSYMPath)
: Dylib(std::move(Dylib)), Mode(Mode), Demangle(Demangle),
DSYMPath(DSYMPath), Exports(std::make_unique<SymbolSet>()),
Ctx(VerifierContext{Diag}) {}
DylibVerifier(llvm::MachO::Records &&Dylib, ReexportedInterfaces &&Reexports,
DiagnosticsEngine *Diag, VerificationMode Mode, bool Demangle,
StringRef DSYMPath)
: Dylib(std::move(Dylib)), Reexports(std::move(Reexports)), Mode(Mode),
Demangle(Demangle), DSYMPath(DSYMPath),
Exports(std::make_unique<SymbolSet>()), Ctx(VerifierContext{Diag}) {}

Result verify(GlobalRecord *R, const FrontendAttrs *FA);
Result verify(ObjCInterfaceRecord *R, const FrontendAttrs *FA);
Expand All @@ -77,6 +82,14 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
// Scan through dylib slices and report any remaining missing exports.
Result verifyRemainingSymbols();

/// Compare and report the attributes represented as
/// load commands in the dylib to the attributes provided via options.
bool verifyBinaryAttrs(const ArrayRef<Target> ProvidedTargets,
const BinaryAttrs &ProvidedBA,
const LibAttrs &ProvidedReexports,
const LibAttrs &ProvidedClients,
const LibAttrs &ProvidedRPaths, const FileType &FT);

/// Initialize target for verification.
void setTarget(const Target &T);

Expand All @@ -87,11 +100,7 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
Result getState() const { return Ctx.FrontendState; }

/// Set different source managers to the same diagnostics engine.
void setSourceManager(SourceManager &SourceMgr) const {
if (!Ctx.Diag)
return;
Ctx.Diag->setSourceManager(&SourceMgr);
}
void setSourceManager(IntrusiveRefCntPtr<SourceManager> SourceMgr);

private:
/// Determine whether to compare declaration to symbol in binary.
Expand All @@ -105,6 +114,10 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
bool shouldIgnoreObsolete(const Record *R, SymbolContext &SymCtx,
const Record *DR);

/// Check if declaration is exported from a reexported library. These
/// symbols should be omitted from the text-api file.
bool shouldIgnoreReexport(const Record *R, SymbolContext &SymCtx) const;

/// Compare the visibility declarations to the linkage of symbol found in
/// dylib.
Result compareVisibility(const Record *R, SymbolContext &SymCtx,
Expand Down Expand Up @@ -154,6 +167,9 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
// Symbols in dylib.
llvm::MachO::Records Dylib;

// Reexported interfaces apart of the library.
ReexportedInterfaces Reexports;

// Controls what class of violations to report.
VerificationMode Mode = VerificationMode::Invalid;

Expand All @@ -171,6 +187,9 @@ class DylibVerifier : llvm::MachO::RecordVisitor {

// Track DWARF provided source location for dylibs.
DWARFContext *DWARFCtx = nullptr;

// Source manager for each unique compiler instance.
llvm::SmallVector<IntrusiveRefCntPtr<SourceManager>, 12> SourceManagers;
};

} // namespace installapi
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/InstallAPI/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class InstallAPIAction : public ASTFrontendAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override {
Ctx.Diags->getClient()->BeginSourceFile(CI.getLangOpts());
Ctx.Verifier->setSourceManager(CI.getSourceManager());
Ctx.Verifier->setSourceManager(CI.getSourceManagerPtr());
return std::make_unique<InstallAPIVisitor>(
CI.getASTContext(), Ctx, CI.getSourceManager(), CI.getPreprocessor());
}
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/InstallAPI/FrontendRecords.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace installapi {
struct FrontendAttrs {
const AvailabilityInfo Avail;
const Decl *D;
const SourceLocation Loc;
const HeaderType Access;
};

Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/InstallAPI/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "llvm/TextAPI/TextAPIWriter.h"
#include "llvm/TextAPI/Utils.h"

using Architecture = llvm::MachO::Architecture;
using ArchitectureSet = llvm::MachO::ArchitectureSet;
using SymbolFlags = llvm::MachO::SymbolFlags;
using RecordLinkage = llvm::MachO::RecordLinkage;
using Record = llvm::MachO::Record;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Lex/ExternalPreprocessorSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ExternalPreprocessorSource {
virtual void ReadDefinedMacros() = 0;

/// Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
virtual void updateOutOfDateIdentifier(const IdentifierInfo &II) = 0;

/// Return the identifier associated with the given ID number.
///
Expand Down
26 changes: 22 additions & 4 deletions clang/include/clang/Lex/HeaderSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,19 @@ struct HeaderFileInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned External : 1;

/// Whether this header is part of a module.
/// Whether this header is part of and built with a module. i.e. it is listed
/// in a module map, and is not `excluded` or `textual`. (same meaning as
/// `ModuleMap::isModular()`).
LLVM_PREFERRED_TYPE(bool)
unsigned isModuleHeader : 1;

/// Whether this header is part of the module that we are building.
/// Whether this header is a `textual header` in a module.
LLVM_PREFERRED_TYPE(bool)
unsigned isTextualModuleHeader : 1;

/// Whether this header is part of the module that we are building, even if it
/// doesn't build with the module. i.e. this will include `excluded` and
/// `textual` headers as well as normal headers.
LLVM_PREFERRED_TYPE(bool)
unsigned isCompilingModuleHeader : 1;

Expand Down Expand Up @@ -128,13 +136,20 @@ struct HeaderFileInfo {

HeaderFileInfo()
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
External(false), isModuleHeader(false), isCompilingModuleHeader(false),
Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {}
External(false), isModuleHeader(false), isTextualModuleHeader(false),
isCompilingModuleHeader(false), Resolved(false),
IndexHeaderMapHeader(false), IsValid(false) {}

/// Retrieve the controlling macro for this header file, if
/// any.
const IdentifierInfo *
getControllingMacro(ExternalPreprocessorSource *External);

/// Update the module membership bits based on the header role.
///
/// isModuleHeader will potentially be set, but not cleared.
/// isTextualModuleHeader will be set or cleared based on the role update.
void mergeModuleMembership(ModuleMap::ModuleHeaderRole Role);
};

/// An external source of header file information, which may supply
Expand Down Expand Up @@ -522,6 +537,9 @@ class HeaderSearch {
///
/// \return false if \#including the file will have no effect or true
/// if we should include it.
///
/// \param M The module to which `File` belongs (this should usually be the
/// SuggestedModule returned by LookupFile/LookupSubframeworkHeader)
bool ShouldEnterIncludeFile(Preprocessor &PP, FileEntryRef File,
bool isImport, bool ModulesEnabled, Module *M,
bool &IsFirstIncludeOfFile);
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Lex/MacroInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ class ModuleMacro : public llvm::FoldingSetNode {
friend class Preprocessor;

/// The name defined by the macro.
IdentifierInfo *II;
const IdentifierInfo *II;

/// The body of the #define, or nullptr if this is a #undef.
MacroInfo *Macro;
Expand All @@ -529,7 +529,7 @@ class ModuleMacro : public llvm::FoldingSetNode {
/// The number of modules whose macros are directly overridden by this one.
unsigned NumOverrides;

ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
ModuleMacro(Module *OwningModule, const IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides)
: II(II), Macro(Macro), OwningModule(OwningModule),
NumOverrides(Overrides.size()) {
Expand All @@ -539,7 +539,7 @@ class ModuleMacro : public llvm::FoldingSetNode {

public:
static ModuleMacro *create(Preprocessor &PP, Module *OwningModule,
IdentifierInfo *II, MacroInfo *Macro,
const IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides);

void Profile(llvm::FoldingSetNodeID &ID) const {
Expand All @@ -553,7 +553,7 @@ class ModuleMacro : public llvm::FoldingSetNode {
}

/// Get the name of the macro.
IdentifierInfo *getName() const { return II; }
const IdentifierInfo *getName() const { return II; }

/// Get the ID of the module that exports this macro.
Module *getOwningModule() const { return OwningModule; }
Expand Down
27 changes: 5 additions & 22 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -736,19 +736,6 @@ class Preprocessor {
State ConditionalStackState = Off;
} PreambleConditionalStack;

/// Function for getting the dependency preprocessor directives of a file.
///
/// These are directives derived from a special form of lexing where the
/// source input is scanned for the preprocessor directives that might have an
/// effect on the dependencies for a compilation unit.
///
/// Enables a client to cache the directives for a file and provide them
/// across multiple compiler invocations.
/// FIXME: Allow returning an error.
using DependencyDirectivesFn = llvm::unique_function<std::optional<
ArrayRef<dependency_directives_scan::Directive>>(FileEntryRef)>;
DependencyDirectivesFn DependencyDirectivesForFile;

/// The current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
///
Expand Down Expand Up @@ -849,7 +836,7 @@ class Preprocessor {
ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
const IdentifierInfo *II) const {
if (II->isOutOfDate())
PP.updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
PP.updateOutOfDateIdentifier(*II);
// FIXME: Find a spare bit on IdentifierInfo and store a
// HasModuleMacros flag.
if (!II->hasMacroDefinition() ||
Expand Down Expand Up @@ -1175,7 +1162,7 @@ class Preprocessor {
/// skipped.
llvm::DenseMap<const char *, unsigned> RecordedSkippedRanges;

void updateOutOfDateIdentifier(IdentifierInfo &II) const;
void updateOutOfDateIdentifier(const IdentifierInfo &II) const;

public:
Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
Expand Down Expand Up @@ -1283,11 +1270,6 @@ class Preprocessor {
/// false if it is producing tokens to be consumed by Parse and Sema.
bool isPreprocessedOutput() const { return PreprocessedOutput; }

/// Set the function used to get dependency directives for a file.
void setDependencyDirectivesFn(DependencyDirectivesFn Fn) {
DependencyDirectivesForFile = std::move(Fn);
}

/// Return true if we are lexing directly from the specified lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
return CurPPLexer == L;
Expand Down Expand Up @@ -1450,14 +1432,15 @@ class Preprocessor {
MacroDirective *MD);

/// Register an exported macro for a module and identifier.
ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
ModuleMacro *addModuleMacro(Module *Mod, const IdentifierInfo *II,
MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
ModuleMacro *getModuleMacro(Module *Mod, const IdentifierInfo *II);

/// Get the list of leaf (non-overridden) module macros for a name.
ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
if (II->isOutOfDate())
updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
updateOutOfDateIdentifier(*II);
auto I = LeafModuleMacros.find(II);
if (I != LeafModuleMacros.end())
return I->second;
Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/Lex/PreprocessorOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,19 @@ class PreprocessorOptions {
/// with support for lifetime-qualified pointers.
ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;

/// Function for getting the dependency preprocessor directives of a file.
///
/// These are directives derived from a special form of lexing where the
/// source input is scanned for the preprocessor directives that might have an
/// effect on the dependencies for a compilation unit.
///
/// Enables a client to cache the directives for a file and provide them
/// across multiple compiler invocations.
/// FIXME: Allow returning an error.
std::function<std::optional<ArrayRef<dependency_directives_scan::Directive>>(
FileEntryRef)>
DependencyDirectivesForFile;

/// Set up preprocessor for RunAnalysis action.
bool SetUpStaticAnalyzer = false;

Expand Down
50 changes: 34 additions & 16 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace clang {
class InMessageExpressionRAIIObject;
class PoisonSEHIdentifiersRAIIObject;
class OMPClause;
class OpenACCClause;
class ObjCTypeParamList;
struct OMPTraitProperty;
struct OMPTraitSelector;
Expand Down Expand Up @@ -328,7 +329,7 @@ class Parser : public CodeCompletionHandler {
};

/// Identifiers which have been declared within a tentative parse.
SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
SmallVector<const IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;

/// Tracker for '<' tokens that might have been intended to be treated as an
/// angle bracket instead of a less-than comparison.
Expand Down Expand Up @@ -1926,15 +1927,11 @@ class Parser : public CodeCompletionHandler {
bool EnteringContext, IdentifierInfo &II,
CXXScopeSpec &SS);

bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
ParsedType ObjectType,
bool ObjectHasErrors,
bool EnteringContext,
bool *MayBePseudoDestructor = nullptr,
bool IsTypename = false,
IdentifierInfo **LastII = nullptr,
bool OnlyNamespace = false,
bool InUsingDeclaration = false);
bool ParseOptionalCXXScopeSpecifier(
CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHasErrors,
bool EnteringContext, bool *MayBePseudoDestructor = nullptr,
bool IsTypename = false, const IdentifierInfo **LastII = nullptr,
bool OnlyNamespace = false, bool InUsingDeclaration = false);

//===--------------------------------------------------------------------===//
// C++11 5.1.2: Lambda expressions
Expand Down Expand Up @@ -3594,11 +3591,26 @@ class Parser : public CodeCompletionHandler {
OpenACCDirectiveKind DirKind;
SourceLocation StartLoc;
SourceLocation EndLoc;
// TODO OpenACC: Add Clause list here once we have a type for that.
SmallVector<OpenACCClause *> Clauses;
// TODO OpenACC: As we implement support for the Atomic, Routine, Cache, and
// Wait constructs, we likely want to put that information in here as well.
};

/// Represents the 'error' state of parsing an OpenACC Clause, and stores
/// whether we can continue parsing, or should give up on the directive.
enum class OpenACCParseCanContinue { Cannot = 0, Can = 1 };

/// A type to represent the state of parsing an OpenACC Clause. Situations
/// that result in an OpenACCClause pointer are a success and can continue
/// parsing, however some other situations can also continue.
/// FIXME: This is better represented as a std::expected when we get C++23.
using OpenACCClauseParseResult =
llvm::PointerIntPair<OpenACCClause *, 1, OpenACCParseCanContinue>;

OpenACCClauseParseResult OpenACCCanContinue();
OpenACCClauseParseResult OpenACCCannotContinue();
OpenACCClauseParseResult OpenACCSuccess(OpenACCClause *Clause);

/// Parses the OpenACC directive (the entire pragma) including the clause
/// list, but does not produce the main AST node.
OpenACCDirectiveParseInfo ParseOpenACCDirective();
Expand All @@ -3613,12 +3625,18 @@ class Parser : public CodeCompletionHandler {
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
/// Parses any parameters for an OpenACC Clause, including required/optional
/// parens.
bool ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
OpenACCClauseKind Kind);
/// Parses a single clause in a clause-list for OpenACC.
bool ParseOpenACCClause(OpenACCDirectiveKind DirKind);
OpenACCClauseParseResult
ParseOpenACCClauseParams(ArrayRef<const OpenACCClause *> ExistingClauses,
OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind,
SourceLocation ClauseLoc);
/// Parses a single clause in a clause-list for OpenACC. Returns nullptr on
/// error.
OpenACCClauseParseResult
ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
OpenACCDirectiveKind DirKind);
/// Parses the clause-list for an OpenACC directive.
void ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
SmallVector<OpenACCClause *>
ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
bool ParseOpenACCWaitArgument();
/// Parses the clause of the 'bind' argument, which can be a string literal or
/// an ID expression.
Expand Down
9 changes: 5 additions & 4 deletions clang/include/clang/Sema/CodeCompleteConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ class CodeCompletionContext {
QualType BaseType;

/// The identifiers for Objective-C selector parts.
ArrayRef<IdentifierInfo *> SelIdents;
ArrayRef<const IdentifierInfo *> SelIdents;

/// The scope specifier that comes before the completion token e.g.
/// "a::b::"
Expand All @@ -378,8 +378,9 @@ class CodeCompletionContext {
: CCKind(CCKind), IsUsingDeclaration(false), SelIdents(std::nullopt) {}

/// Construct a new code-completion context of the given kind.
CodeCompletionContext(Kind CCKind, QualType T,
ArrayRef<IdentifierInfo *> SelIdents = std::nullopt)
CodeCompletionContext(
Kind CCKind, QualType T,
ArrayRef<const IdentifierInfo *> SelIdents = std::nullopt)
: CCKind(CCKind), IsUsingDeclaration(false), SelIdents(SelIdents) {
if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess ||
CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage ||
Expand All @@ -406,7 +407,7 @@ class CodeCompletionContext {
QualType getBaseType() const { return BaseType; }

/// Retrieve the Objective-C selector identifiers.
ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; }
ArrayRef<const IdentifierInfo *> getSelIdents() const { return SelIdents; }

/// Determines whether we want C++ constructors as results within this
/// context.
Expand Down
23 changes: 11 additions & 12 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ class UnqualifiedId {
union {
/// When Kind == IK_Identifier, the parsed identifier, or when
/// Kind == IK_UserLiteralId, the identifier suffix.
IdentifierInfo *Identifier;
const IdentifierInfo *Identifier;

/// When Kind == IK_OperatorFunctionId, the overloaded operator
/// that we parsed.
Expand Down Expand Up @@ -1111,7 +1111,7 @@ class UnqualifiedId {
/// \param IdLoc the location of the parsed identifier.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
Kind = UnqualifiedIdKind::IK_Identifier;
Identifier = const_cast<IdentifierInfo *>(Id);
Identifier = Id;
StartLocation = EndLocation = IdLoc;
}

Expand Down Expand Up @@ -1154,9 +1154,9 @@ class UnqualifiedId {
///
/// \param IdLoc the location of the identifier.
void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
SourceLocation IdLoc) {
SourceLocation IdLoc) {
Kind = UnqualifiedIdKind::IK_LiteralOperatorId;
Identifier = const_cast<IdentifierInfo *>(Id);
Identifier = Id;
StartLocation = OpLoc;
EndLocation = IdLoc;
}
Expand Down Expand Up @@ -1225,7 +1225,7 @@ class UnqualifiedId {
/// \param Id the identifier.
void setImplicitSelfParam(const IdentifierInfo *Id) {
Kind = UnqualifiedIdKind::IK_ImplicitSelfParam;
Identifier = const_cast<IdentifierInfo *>(Id);
Identifier = Id;
StartLocation = EndLocation = SourceLocation();
}

Expand Down Expand Up @@ -1327,7 +1327,7 @@ struct DeclaratorChunk {
/// Parameter type lists will have type info (if the actions module provides
/// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
struct ParamInfo {
IdentifierInfo *Ident;
const IdentifierInfo *Ident;
SourceLocation IdentLoc;
Decl *Param;

Expand All @@ -1339,11 +1339,10 @@ struct DeclaratorChunk {
std::unique_ptr<CachedTokens> DefaultArgTokens;

ParamInfo() = default;
ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
Decl *param,
ParamInfo(const IdentifierInfo *ident, SourceLocation iloc, Decl *param,
std::unique_ptr<CachedTokens> DefArgTokens = nullptr)
: Ident(ident), IdentLoc(iloc), Param(param),
DefaultArgTokens(std::move(DefArgTokens)) {}
: Ident(ident), IdentLoc(iloc), Param(param),
DefaultArgTokens(std::move(DefArgTokens)) {}
};

struct TypeAndRange {
Expand Down Expand Up @@ -2326,7 +2325,7 @@ class Declarator {
return BindingGroup.isSet();
}

IdentifierInfo *getIdentifier() const {
const IdentifierInfo *getIdentifier() const {
if (Name.getKind() == UnqualifiedIdKind::IK_Identifier)
return Name.Identifier;

Expand All @@ -2335,7 +2334,7 @@ class Declarator {
SourceLocation getIdentifierLoc() const { return Name.StartLocation; }

/// Set the name of this declarator to be the given identifier.
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) {
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
Name.setIdentifier(Id, IdLoc);
}

Expand Down
7 changes: 4 additions & 3 deletions clang/include/clang/Sema/ParsedTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ namespace clang {
SourceLocation TemplateNameLoc;

/// FIXME: Temporarily stores the name of a specialization
IdentifierInfo *Name;
const IdentifierInfo *Name;

/// FIXME: Temporarily stores the overloaded operator kind.
OverloadedOperatorKind Operator;
Expand Down Expand Up @@ -197,7 +197,7 @@ namespace clang {
/// appends it to List.
static TemplateIdAnnotation *
Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
SourceLocation LAngleLoc, SourceLocation RAngleLoc,
ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
Expand Down Expand Up @@ -236,7 +236,8 @@ namespace clang {
TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;

TemplateIdAnnotation(SourceLocation TemplateKWLoc,
SourceLocation TemplateNameLoc, IdentifierInfo *Name,
SourceLocation TemplateNameLoc,
const IdentifierInfo *Name,
OverloadedOperatorKind OperatorKind,
ParsedTemplateTy OpaqueTemplateName,
TemplateNameKind TemplateKind,
Expand Down
498 changes: 125 additions & 373 deletions clang/include/clang/Sema/Sema.h

Large diffs are not rendered by default.

224 changes: 224 additions & 0 deletions clang/include/clang/Sema/SemaBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
//===--- SemaBase.h - Common utilities for semantic analysis-----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the SemaBase class, which provides utilities for Sema
// and its parts like SemaOpenACC.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMABASE_H
#define LLVM_CLANG_SEMA_SEMABASE_H

#include "clang/AST/Decl.h"
#include "clang/AST/Redeclarable.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/DenseMap.h"
#include <optional>
#include <type_traits>
#include <utility>
#include <vector>

namespace clang {

class ASTContext;
class DiagnosticsEngine;
class LangOptions;
class Sema;

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

Sema &SemaRef;

ASTContext &getASTContext() const;
DiagnosticsEngine &getDiagnostics() const;
const LangOptions &getLangOpts() const;

/// Helper class that creates diagnostics with optional
/// template instantiation stacks.
///
/// This class provides a wrapper around the basic DiagnosticBuilder
/// class that emits diagnostics. ImmediateDiagBuilder is
/// responsible for emitting the diagnostic (as DiagnosticBuilder
/// does) and, if the diagnostic comes from inside a template
/// instantiation, printing the template instantiation stack as
/// well.
class ImmediateDiagBuilder : public DiagnosticBuilder {
Sema &SemaRef;
unsigned DiagID;

public:
ImmediateDiagBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
: DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
ImmediateDiagBuilder(DiagnosticBuilder &&DB, Sema &SemaRef, unsigned DiagID)
: DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}

// This is a cunning lie. DiagnosticBuilder actually performs move
// construction in its copy constructor (but due to varied uses, it's not
// possible to conveniently express this as actual move construction). So
// the default copy ctor here is fine, because the base class disables the
// source anyway, so the user-defined ~ImmediateDiagBuilder is a safe no-op
// in that case anwyay.
ImmediateDiagBuilder(const ImmediateDiagBuilder &) = default;

~ImmediateDiagBuilder();

/// Teach operator<< to produce an object of the correct type.
template <typename T>
friend const ImmediateDiagBuilder &
operator<<(const ImmediateDiagBuilder &Diag, const T &Value) {
const DiagnosticBuilder &BaseDiag = Diag;
BaseDiag << Value;
return Diag;
}

// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
template <typename T,
typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
const ImmediateDiagBuilder &operator<<(T &&V) const {
const DiagnosticBuilder &BaseDiag = *this;
BaseDiag << std::move(V);
return *this;
}
};

/// A generic diagnostic builder for errors which may or may not be deferred.
///
/// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch)
/// which are not allowed to appear inside __device__ functions and are
/// allowed to appear in __host__ __device__ functions only if the host+device
/// function is never codegen'ed.
///
/// To handle this, we use the notion of "deferred diagnostics", where we
/// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed.
///
/// This class lets you emit either a regular diagnostic, a deferred
/// diagnostic, or no diagnostic at all, according to an argument you pass to
/// its constructor, thus simplifying the process of creating these "maybe
/// deferred" diagnostics.
class SemaDiagnosticBuilder {
public:
enum Kind {
/// Emit no diagnostics.
K_Nop,
/// Emit the diagnostic immediately (i.e., behave like Sema::Diag()).
K_Immediate,
/// Emit the diagnostic immediately, and, if it's a warning or error, also
/// emit a call stack showing how this function can be reached by an a
/// priori known-emitted function.
K_ImmediateWithCallStack,
/// Create a deferred diagnostic, which is emitted only if the function
/// it's attached to is codegen'ed. Also emit a call stack as with
/// K_ImmediateWithCallStack.
K_Deferred
};

SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
const FunctionDecl *Fn, Sema &S);
SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D);
SemaDiagnosticBuilder(const SemaDiagnosticBuilder &) = default;

// The copy and move assignment operator is defined as deleted pending
// further motivation.
SemaDiagnosticBuilder &operator=(const SemaDiagnosticBuilder &) = delete;
SemaDiagnosticBuilder &operator=(SemaDiagnosticBuilder &&) = delete;

~SemaDiagnosticBuilder();

bool isImmediate() const { return ImmediateDiag.has_value(); }

/// Convertible to bool: True if we immediately emitted an error, false if
/// we didn't emit an error or we created a deferred error.
///
/// Example usage:
///
/// if (SemaDiagnosticBuilder(...) << foo << bar)
/// return ExprError();
///
/// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably
/// want to use these instead of creating a SemaDiagnosticBuilder yourself.
operator bool() const { return isImmediate(); }

template <typename T>
friend const SemaDiagnosticBuilder &
operator<<(const SemaDiagnosticBuilder &Diag, const T &Value) {
if (Diag.ImmediateDiag)
*Diag.ImmediateDiag << Value;
else if (Diag.PartialDiagId)
Diag.getDeviceDeferredDiags()[Diag.Fn][*Diag.PartialDiagId].second
<< Value;
return Diag;
}

// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
template <typename T,
typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
const SemaDiagnosticBuilder &operator<<(T &&V) const {
if (ImmediateDiag)
*ImmediateDiag << std::move(V);
else if (PartialDiagId)
getDeviceDeferredDiags()[Fn][*PartialDiagId].second << std::move(V);
return *this;
}

friend const SemaDiagnosticBuilder &
operator<<(const SemaDiagnosticBuilder &Diag, const PartialDiagnostic &PD);

void AddFixItHint(const FixItHint &Hint) const;

friend ExprResult ExprError(const SemaDiagnosticBuilder &) {
return ExprError();
}
friend StmtResult StmtError(const SemaDiagnosticBuilder &) {
return StmtError();
}
operator ExprResult() const { return ExprError(); }
operator StmtResult() const { return StmtError(); }
operator TypeResult() const { return TypeError(); }
operator DeclResult() const { return DeclResult(true); }
operator MemInitResult() const { return MemInitResult(true); }

using DeferredDiagnosticsType =
llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
std::vector<PartialDiagnosticAt>>;

private:
Sema &S;
SourceLocation Loc;
unsigned DiagID;
const FunctionDecl *Fn;
bool ShowCallStack;

// Invariant: At most one of these Optionals has a value.
// FIXME: Switch these to a Variant once that exists.
std::optional<ImmediateDiagBuilder> ImmediateDiag;
std::optional<unsigned> PartialDiagId;

DeferredDiagnosticsType &getDeviceDeferredDiags() const;
};

/// Emit a diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID,
bool DeferHint = false);

/// Emit a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic &PD,
bool DeferHint = false);
};

} // namespace clang

#endif
37 changes: 37 additions & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===----- SemaHLSL.h ----- Semantic Analysis for HLSL 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 for HLSL constructs.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMAHLSL_H
#define LLVM_CLANG_SEMA_SEMAHLSL_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"

namespace clang {

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

Decl *ActOnStartHLSLBuffer(Scope *BufferScope, bool CBuffer,
SourceLocation KwLoc, IdentifierInfo *Ident,
SourceLocation IdentLoc, SourceLocation LBrace);
void ActOnFinishHLSLBuffer(Decl *Dcl, SourceLocation RBrace);
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMAHLSL_H
69 changes: 56 additions & 13 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,66 @@
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/SemaBase.h"
#include <variant>

namespace clang {
class OpenACCClause;

class ASTContext;
class DiagnosticEngine;
class LangOptions;
class Sema;

class SemaOpenACC {
class SemaOpenACC : public SemaBase {
public:
SemaOpenACC(Sema &S);
/// A type to represent all the data for an OpenACC Clause that has been
/// parsed, but not yet created/semantically analyzed. This is effectively a
/// discriminated union on the 'Clause Kind', with all of the individual
/// clause details stored in a std::variant.
class OpenACCParsedClause {
OpenACCDirectiveKind DirKind;
OpenACCClauseKind ClauseKind;
SourceRange ClauseRange;
SourceLocation LParenLoc;

struct DefaultDetails {
OpenACCDefaultClauseKind DefaultClauseKind;
};

std::variant<DefaultDetails> Details;

public:
OpenACCParsedClause(OpenACCDirectiveKind DirKind,
OpenACCClauseKind ClauseKind, SourceLocation BeginLoc)
: DirKind(DirKind), ClauseKind(ClauseKind), ClauseRange(BeginLoc, {}) {}

OpenACCDirectiveKind getDirectiveKind() const { return DirKind; }

OpenACCClauseKind getClauseKind() const { return ClauseKind; }

ASTContext &getASTContext() const;
DiagnosticsEngine &getDiagnostics() const;
const LangOptions &getLangOpts() const;
SourceLocation getBeginLoc() const { return ClauseRange.getBegin(); }

Sema &SemaRef;
SourceLocation getLParenLoc() const { return LParenLoc; }

SourceLocation getEndLoc() const { return ClauseRange.getEnd(); }

OpenACCDefaultClauseKind getDefaultClauseKind() const {
assert(ClauseKind == OpenACCClauseKind::Default &&
"Parsed clause is not a default clause");
return std::get<DefaultDetails>(Details).DefaultClauseKind;
}

void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }

void setDefaultDetails(OpenACCDefaultClauseKind DefKind) {
assert(ClauseKind == OpenACCClauseKind::Default &&
"Parsed clause is not a default clause");
Details = DefaultDetails{DefKind};
}
};

SemaOpenACC(Sema &S);

/// Called after parsing an OpenACC Clause so that it can be checked.
bool ActOnClause(OpenACCClauseKind ClauseKind, SourceLocation StartLoc);
OpenACCClause *ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
OpenACCParsedClause &Clause);

/// Called after the construct has been parsed, but clauses haven't been
/// parsed. This allows us to diagnose not-implemented, as well as set up any
Expand All @@ -63,7 +103,10 @@ class SemaOpenACC {
/// declaration group or associated statement.
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc,
SourceLocation EndLoc, StmtResult AssocStmt);
SourceLocation EndLoc,
ArrayRef<OpenACCClause *> Clauses,
StmtResult AssocStmt);

/// Called after the directive has been completely parsed, including the
/// declaration group or associated statement.
DeclGroupRef ActOnEndDeclDirective();
Expand Down
65 changes: 65 additions & 0 deletions clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//===----- SemaSYCL.h ------- Semantic Analysis for SYCL 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 for SYCL constructs.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SEMASYCL_H
#define LLVM_CLANG_SEMA_SEMASYCL_H

#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseSet.h"

namespace clang {

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

/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
/// context is "used as device code".
///
/// - If CurLexicalContext is a kernel function or it is known that the
/// function will be emitted for the device, emits the diagnostics
/// immediately.
/// - If CurLexicalContext is a function and we are compiling
/// for the device, but we don't know yet that this function will be
/// codegen'ed for the devive, creates a diagnostic which is emitted if and
/// when we realize that the function will be codegen'ed.
///
/// Example usage:
///
/// Diagnose __float128 type usage only from SYCL device code if the current
/// target doesn't support it
/// if (!S.Context.getTargetInfo().hasFloat128Type() &&
/// S.getLangOpts().SYCLIsDevice)
/// DiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128";
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);

void deepTypeCheckForDevice(SourceLocation UsedAt,
llvm::DenseSet<QualType> Visited,
ValueDecl *DeclToCheck);

ExprResult BuildUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
TypeSourceInfo *TSI);
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen,
ParsedType ParsedTy);
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SEMASYCL_H
27 changes: 7 additions & 20 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1082,34 +1082,20 @@ class ASTReader

/// The set of lookup results that we have faked in order to support
/// merging of partially deserialized decls but that we have not yet removed.
llvm::SmallMapVector<IdentifierInfo *, SmallVector<NamedDecl*, 2>, 16>
PendingFakeLookupResults;
llvm::SmallMapVector<const IdentifierInfo *, SmallVector<NamedDecl *, 2>, 16>
PendingFakeLookupResults;

/// The generation number of each identifier, which keeps track of
/// the last time we loaded information about this identifier.
llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration;

class InterestingDecl {
Decl *D;
bool DeclHasPendingBody;

public:
InterestingDecl(Decl *D, bool HasBody)
: D(D), DeclHasPendingBody(HasBody) {}

Decl *getDecl() { return D; }

/// Whether the declaration has a pending body.
bool hasPendingBody() { return DeclHasPendingBody; }
};
llvm::DenseMap<const IdentifierInfo *, unsigned> IdentifierGeneration;

/// Contains declarations and definitions that could be
/// "interesting" to the ASTConsumer, when we get that AST consumer.
///
/// "Interesting" declarations are those that have data that may
/// need to be emitted, such as inline function definitions or
/// Objective-C protocols.
std::deque<InterestingDecl> PotentiallyInterestingDecls;
std::deque<Decl *> PotentiallyInterestingDecls;

/// The list of deduced function types that we have not yet read, because
/// they might contain a deduced return type that refers to a local type
Expand Down Expand Up @@ -1506,6 +1492,7 @@ class ASTReader
getModuleFileLevelDecls(ModuleFile &Mod);

private:
bool isConsumerInterestedIn(Decl *D);
void PassInterestingDeclsToConsumer();
void PassInterestingDeclToConsumer(Decl *D);

Expand Down Expand Up @@ -2344,10 +2331,10 @@ class ASTReader
void ReadDefinedMacros() override;

/// Update an out-of-date identifier.
void updateOutOfDateIdentifier(IdentifierInfo &II) override;
void updateOutOfDateIdentifier(const IdentifierInfo &II) override;

/// Note that this identifier is up-to-date.
void markIdentifierUpToDate(IdentifierInfo *II);
void markIdentifierUpToDate(const IdentifierInfo *II);

/// Load all external visible decls in the given DeclContext.
void completeVisibleDeclsMap(const DeclContext *DC) override;
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/ADT/APSInt.h"

namespace clang {
class OpenACCClause;
class OMPTraitInfo;
class OMPChildren;

Expand Down Expand Up @@ -278,6 +279,12 @@ class ASTRecordReader
/// Read an OpenMP children, advancing Idx.
void readOMPChildren(OMPChildren *Data);

/// Read an OpenACC clause, advancing Idx.
OpenACCClause *readOpenACCClause();

/// Read a list of OpenACC clauses into the passed SmallVector.
void readOpenACCClauseList(MutableArrayRef<const OpenACCClause *> Clauses);

/// Read a source location, advancing Idx.
SourceLocation readSourceLocation(LocSeq *Seq = nullptr) {
return Reader->ReadSourceLocation(*F, Record, Idx, Seq);
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

namespace clang {

class OpenACCClause;
class TypeLoc;

/// An object for streaming information to a record.
Expand Down Expand Up @@ -292,6 +293,12 @@ class ASTRecordWriter
/// Writes data related to the OpenMP directives.
void writeOMPChildren(OMPChildren *Data);

/// Writes out a single OpenACC Clause.
void writeOpenACCClause(const OpenACCClause *C);

/// Writes out a list of OpenACC clauses.
void writeOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses);

/// Emit a string.
void AddString(StringRef Str) {
return Writer->AddString(Str, *Record);
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,15 @@ def PthreadLockChecker : Checker<"PthreadLock">,
def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
WeakDependencies<[NonNullParamChecker]>,
CheckerOptions<[
CmdLineOption<Boolean,
"Pedantic",
"If false, assume that stream operations which are often not "
"checked for error do not fail."
"fail.",
"false",
InAlpha>
]>,
Documentation<HasDocumentation>;

def SimpleStreamChecker : Checker<"SimpleStream">,
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/ARCMigrate/ObjCMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ static bool IsValidIdentifier(ASTContext &Ctx,
return false;
std::string NameString = Name;
NameString[0] = toLowercase(NameString[0]);
IdentifierInfo *II = &Ctx.Idents.get(NameString);
const IdentifierInfo *II = &Ctx.Idents.get(NameString);
return II->getTokenID() == tok::identifier;
}

Expand All @@ -1166,7 +1166,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
if (OIT_Family != OIT_None)
return false;

IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
const IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
Selector SetterSelector =
SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
PP.getSelectorTable(),
Expand Down Expand Up @@ -1311,7 +1311,8 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
std::string StringLoweredClassName = LoweredClassName.lower();
LoweredClassName = StringLoweredClassName;

IdentifierInfo *MethodIdName = OM->getSelector().getIdentifierInfoForSlot(0);
const IdentifierInfo *MethodIdName =
OM->getSelector().getIdentifierInfoForSlot(0);
// Handle method with no name at its first selector slot; e.g. + (id):(int)x.
if (!MethodIdName)
return;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/ARCMigrate/TransAPIUses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class APIChecker : public RecursiveASTVisitor<APIChecker> {
getReturnValueSel = sels.getUnarySelector(&ids.get("getReturnValue"));
setReturnValueSel = sels.getUnarySelector(&ids.get("setReturnValue"));

IdentifierInfo *selIds[2];
const IdentifierInfo *selIds[2];
selIds[0] = &ids.get("getArgument");
selIds[1] = &ids.get("atIndex");
getArgumentSel = sels.getSelector(2, selIds);
Expand Down
13 changes: 5 additions & 8 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(

TemplateTemplateParmDecl *CanonTTP = TemplateTemplateParmDecl::Create(
*this, getTranslationUnitDecl(), SourceLocation(), TTP->getDepth(),
TTP->getPosition(), TTP->isParameterPack(), nullptr,
TTP->getPosition(), TTP->isParameterPack(), nullptr, /*Typename=*/false,
TemplateParameterList::Create(*this, SourceLocation(), SourceLocation(),
CanonParams, SourceLocation(),
/*RequiresClause=*/nullptr));
Expand Down Expand Up @@ -6929,16 +6929,13 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
// typedef typename T::type T1;
// typedef typename T1::type T2;
if (const auto *DNT = T->getAs<DependentNameType>())
return NestedNameSpecifier::Create(
*this, DNT->getQualifier(),
const_cast<IdentifierInfo *>(DNT->getIdentifier()));
return NestedNameSpecifier::Create(*this, DNT->getQualifier(),
DNT->getIdentifier());
if (const auto *DTST = T->getAs<DependentTemplateSpecializationType>())
return NestedNameSpecifier::Create(*this, DTST->getQualifier(), true,
const_cast<Type *>(T));
return NestedNameSpecifier::Create(*this, DTST->getQualifier(), true, T);

// TODO: Set 'Template' parameter to true for other template types.
return NestedNameSpecifier::Create(*this, nullptr, false,
const_cast<Type *>(T));
return NestedNameSpecifier::Create(*this, nullptr, false, T);
}

case NestedNameSpecifier::Global:
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5952,7 +5952,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
ToD, D, Importer.getToContext(),
Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr,
D->getDepth(), D->getPosition(), D->isParameterPack(),
(*NameOrErr).getAsIdentifierInfo(), *TemplateParamsOrErr))
(*NameOrErr).getAsIdentifierInfo(), D->wasDeclaredWithTypename(),
*TemplateParamsOrErr))
return ToD;

if (D->hasDefaultArgument()) {
Expand Down Expand Up @@ -8383,8 +8384,8 @@ ASTNodeImporter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
return std::move(Err);

PseudoDestructorTypeStorage Storage;
if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) {
IdentifierInfo *ToII = Importer.Import(FromII);
if (const IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) {
const IdentifierInfo *ToII = Importer.Import(FromII);
ExpectedSLoc ToDestroyedTypeLocOrErr = import(E->getDestroyedTypeLoc());
if (!ToDestroyedTypeLocOrErr)
return ToDestroyedTypeLocOrErr.takeError();
Expand Down Expand Up @@ -10194,7 +10195,7 @@ Expected<Selector> ASTImporter::Import(Selector FromSel) {
if (FromSel.isNull())
return Selector{};

SmallVector<IdentifierInfo *, 4> Idents;
SmallVector<const IdentifierInfo *, 4> Idents;
Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
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 @@ -98,6 +98,7 @@ add_clang_library(clangAST
NSAPI.cpp
ODRDiagsEmitter.cpp
ODRHash.cpp
OpenACCClause.cpp
OpenMPClause.cpp
OSLog.cpp
ParentMap.cpp
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/AST/ComputeDependence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,16 @@ ExprDependence clang::computeDependence(CXXThisExpr *E) {
// 'this' is type-dependent if the class type of the enclosing
// member function is dependent (C++ [temp.dep.expr]p2)
auto D = toExprDependenceForImpliedType(E->getType()->getDependence());

// If a lambda with an explicit object parameter captures '*this', then
// 'this' now refers to the captured copy of lambda, and if the lambda
// is type-dependent, so is the object and thus 'this'.
//
// Note: The standard does not mention this case explicitly, but we need
// to do this so we can mark NSDM accesses as dependent.
if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
D |= ExprDependence::Type;

assert(!(D & ExprDependence::UnexpandedPack));
return D;
}
Expand Down
18 changes: 10 additions & 8 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2913,10 +2913,10 @@ VarDecl::setInstantiationOfStaticDataMember(VarDecl *VD,
//===----------------------------------------------------------------------===//

ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg) {
SourceLocation StartLoc, SourceLocation IdLoc,
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass S,
Expr *DefArg) {
return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo,
S, DefArg);
}
Expand Down Expand Up @@ -4511,7 +4511,7 @@ unsigned FunctionDecl::getODRHash() {

FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle) {
return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
Expand Down Expand Up @@ -5438,7 +5438,7 @@ IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC,

IndirectFieldDecl *
IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T,
const IdentifierInfo *Id, QualType T,
llvm::MutableArrayRef<NamedDecl *> CH) {
return new (C, DC) IndirectFieldDecl(C, DC, L, Id, T, CH);
}
Expand All @@ -5461,7 +5461,8 @@ void TypeDecl::anchor() {}

TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo) {
const IdentifierInfo *Id,
TypeSourceInfo *TInfo) {
return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}

Expand Down Expand Up @@ -5511,7 +5512,8 @@ TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {

TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
SourceLocation IdLoc,
const IdentifierInfo *Id,
TypeSourceInfo *TInfo) {
return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
Expand Down
94 changes: 38 additions & 56 deletions clang/lib/AST/DeclObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
//===----------------------------------------------------------------------===//

ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
IdentifierInfo *Id, SourceLocation nameLoc,
const IdentifierInfo *Id,
SourceLocation nameLoc,
SourceLocation atStartLoc)
: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
setAtStartLoc(atStartLoc);
Expand Down Expand Up @@ -378,10 +379,8 @@ SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {
/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
/// with name 'PropertyId' in the primary class; including those in protocols
/// (direct or indirect) used by the primary class.
ObjCPropertyDecl *
ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const {
ObjCPropertyDecl *ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
return nullptr;
Expand Down Expand Up @@ -1539,14 +1538,10 @@ void ObjCTypeParamList::gatherDefaultTypeArgs(
// ObjCInterfaceDecl
//===----------------------------------------------------------------------===//

ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
DeclContext *DC,
SourceLocation atLoc,
IdentifierInfo *Id,
ObjCTypeParamList *typeParamList,
ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc,
bool isInternal){
ObjCInterfaceDecl *ObjCInterfaceDecl::Create(
const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {
auto *Result = new (C, DC)
ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
isInternal);
Expand All @@ -1564,12 +1559,10 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
return Result;
}

ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
SourceLocation AtLoc, IdentifierInfo *Id,
ObjCTypeParamList *typeParamList,
SourceLocation CLoc,
ObjCInterfaceDecl *PrevDecl,
bool IsInternal)
ObjCInterfaceDecl::ObjCInterfaceDecl(
const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal)
: ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
redeclarable_base(C) {
setPreviousDecl(PrevDecl);
Expand Down Expand Up @@ -1751,8 +1744,8 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
/// categories for this class and returns it. Name of the category is passed
/// in 'CategoryId'. If category not found, return 0;
///
ObjCCategoryDecl *
ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
ObjCCategoryDecl *ObjCInterfaceDecl::FindCategoryDeclaration(
const IdentifierInfo *CategoryId) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
return nullptr;
Expand Down Expand Up @@ -1838,10 +1831,10 @@ void ObjCIvarDecl::anchor() {}

ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW,
bool synthesized) {
SourceLocation IdLoc,
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, AccessControl ac,
Expr *BW, bool synthesized) {
if (DC) {
// Ivar's can only appear in interfaces, implementations (via synthesized
// properties), and class extensions (via direct declaration, or synthesized
Expand Down Expand Up @@ -2120,28 +2113,23 @@ void ObjCProtocolDecl::setHasODRHash(bool HasHash) {

void ObjCCategoryDecl::anchor() {}

ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc,
IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc,
SourceLocation IvarRBraceLoc)
ObjCCategoryDecl::ObjCCategoryDecl(
DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc, const IdentifierInfo *Id,
ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc)
: ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
setTypeParamList(typeParamList);
}

ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation AtLoc,
SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc,
IdentifierInfo *Id,
ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc,
SourceLocation IvarRBraceLoc) {
ObjCCategoryDecl *ObjCCategoryDecl::Create(
ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
SourceLocation IvarRBraceLoc) {
auto *CatDecl =
new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
IDecl, typeParamList, IvarLBraceLoc,
Expand Down Expand Up @@ -2190,13 +2178,10 @@ void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {

void ObjCCategoryImplDecl::anchor() {}

ObjCCategoryImplDecl *
ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
ObjCInterfaceDecl *ClassInterface,
SourceLocation nameLoc,
SourceLocation atStartLoc,
SourceLocation CategoryNameLoc) {
ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(
ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
ObjCInterfaceDecl *ClassInterface, SourceLocation nameLoc,
SourceLocation atStartLoc, SourceLocation CategoryNameLoc) {
if (ClassInterface && ClassInterface->hasDefinition())
ClassInterface = ClassInterface->getDefinition();
return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
Expand Down Expand Up @@ -2365,14 +2350,11 @@ ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {

void ObjCPropertyDecl::anchor() {}

ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id,
SourceLocation AtLoc,
SourceLocation LParenLoc,
QualType T,
TypeSourceInfo *TSI,
PropertyControl propControl) {
ObjCPropertyDecl *
ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
const IdentifierInfo *Id, SourceLocation AtLoc,
SourceLocation LParenLoc, QualType T,
TypeSourceInfo *TSI, PropertyControl propControl) {
return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
propControl);
}
Expand Down
Loading