Skip to content

Commit 0364034

Browse files
author
Jenkins
committed
merge main into amd-staging
Change-Id: Ib3af6ad2026408b6d8c2e1d59b34b7aad4546df6
2 parents 6dea75a + b88a1dd commit 0364034

File tree

32 files changed

+1477
-1026
lines changed

32 files changed

+1477
-1026
lines changed

clang/include/clang/Sema/Sema.h

+3-201
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "clang/Sema/ObjCMethodList.h"
5656
#include "clang/Sema/Ownership.h"
5757
#include "clang/Sema/Scope.h"
58+
#include "clang/Sema/SemaBase.h"
5859
#include "clang/Sema/SemaConcept.h"
5960
#include "clang/Sema/TypoCorrection.h"
6061
#include "clang/Sema/Weak.h"
@@ -422,7 +423,7 @@ enum class TemplateDeductionResult {
422423

423424
/// Sema - This implements semantic analysis and AST building for C.
424425
/// \nosubgrouping
425-
class Sema final {
426+
class Sema final : public SemaBase {
426427
// Table of Contents
427428
// -----------------
428429
// 1. Semantic Analysis (Sema.cpp)
@@ -512,195 +513,6 @@ class Sema final {
512513
///
513514
void addExternalSource(ExternalSemaSource *E);
514515

515-
/// Helper class that creates diagnostics with optional
516-
/// template instantiation stacks.
517-
///
518-
/// This class provides a wrapper around the basic DiagnosticBuilder
519-
/// class that emits diagnostics. ImmediateDiagBuilder is
520-
/// responsible for emitting the diagnostic (as DiagnosticBuilder
521-
/// does) and, if the diagnostic comes from inside a template
522-
/// instantiation, printing the template instantiation stack as
523-
/// well.
524-
class ImmediateDiagBuilder : public DiagnosticBuilder {
525-
Sema &SemaRef;
526-
unsigned DiagID;
527-
528-
public:
529-
ImmediateDiagBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
530-
: DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
531-
ImmediateDiagBuilder(DiagnosticBuilder &&DB, Sema &SemaRef, unsigned DiagID)
532-
: DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
533-
534-
// This is a cunning lie. DiagnosticBuilder actually performs move
535-
// construction in its copy constructor (but due to varied uses, it's not
536-
// possible to conveniently express this as actual move construction). So
537-
// the default copy ctor here is fine, because the base class disables the
538-
// source anyway, so the user-defined ~ImmediateDiagBuilder is a safe no-op
539-
// in that case anwyay.
540-
ImmediateDiagBuilder(const ImmediateDiagBuilder &) = default;
541-
542-
~ImmediateDiagBuilder() {
543-
// If we aren't active, there is nothing to do.
544-
if (!isActive())
545-
return;
546-
547-
// Otherwise, we need to emit the diagnostic. First clear the diagnostic
548-
// builder itself so it won't emit the diagnostic in its own destructor.
549-
//
550-
// This seems wasteful, in that as written the DiagnosticBuilder dtor will
551-
// do its own needless checks to see if the diagnostic needs to be
552-
// emitted. However, because we take care to ensure that the builder
553-
// objects never escape, a sufficiently smart compiler will be able to
554-
// eliminate that code.
555-
Clear();
556-
557-
// Dispatch to Sema to emit the diagnostic.
558-
SemaRef.EmitCurrentDiagnostic(DiagID);
559-
}
560-
561-
/// Teach operator<< to produce an object of the correct type.
562-
template <typename T>
563-
friend const ImmediateDiagBuilder &
564-
operator<<(const ImmediateDiagBuilder &Diag, const T &Value) {
565-
const DiagnosticBuilder &BaseDiag = Diag;
566-
BaseDiag << Value;
567-
return Diag;
568-
}
569-
570-
// It is necessary to limit this to rvalue reference to avoid calling this
571-
// function with a bitfield lvalue argument since non-const reference to
572-
// bitfield is not allowed.
573-
template <typename T,
574-
typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
575-
const ImmediateDiagBuilder &operator<<(T &&V) const {
576-
const DiagnosticBuilder &BaseDiag = *this;
577-
BaseDiag << std::move(V);
578-
return *this;
579-
}
580-
};
581-
582-
/// A generic diagnostic builder for errors which may or may not be deferred.
583-
///
584-
/// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch)
585-
/// which are not allowed to appear inside __device__ functions and are
586-
/// allowed to appear in __host__ __device__ functions only if the host+device
587-
/// function is never codegen'ed.
588-
///
589-
/// To handle this, we use the notion of "deferred diagnostics", where we
590-
/// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed.
591-
///
592-
/// This class lets you emit either a regular diagnostic, a deferred
593-
/// diagnostic, or no diagnostic at all, according to an argument you pass to
594-
/// its constructor, thus simplifying the process of creating these "maybe
595-
/// deferred" diagnostics.
596-
class SemaDiagnosticBuilder {
597-
public:
598-
enum Kind {
599-
/// Emit no diagnostics.
600-
K_Nop,
601-
/// Emit the diagnostic immediately (i.e., behave like Sema::Diag()).
602-
K_Immediate,
603-
/// Emit the diagnostic immediately, and, if it's a warning or error, also
604-
/// emit a call stack showing how this function can be reached by an a
605-
/// priori known-emitted function.
606-
K_ImmediateWithCallStack,
607-
/// Create a deferred diagnostic, which is emitted only if the function
608-
/// it's attached to is codegen'ed. Also emit a call stack as with
609-
/// K_ImmediateWithCallStack.
610-
K_Deferred
611-
};
612-
613-
SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
614-
const FunctionDecl *Fn, Sema &S);
615-
SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D);
616-
SemaDiagnosticBuilder(const SemaDiagnosticBuilder &) = default;
617-
618-
// The copy and move assignment operator is defined as deleted pending
619-
// further motivation.
620-
SemaDiagnosticBuilder &operator=(const SemaDiagnosticBuilder &) = delete;
621-
SemaDiagnosticBuilder &operator=(SemaDiagnosticBuilder &&) = delete;
622-
623-
~SemaDiagnosticBuilder();
624-
625-
bool isImmediate() const { return ImmediateDiag.has_value(); }
626-
627-
/// Convertible to bool: True if we immediately emitted an error, false if
628-
/// we didn't emit an error or we created a deferred error.
629-
///
630-
/// Example usage:
631-
///
632-
/// if (SemaDiagnosticBuilder(...) << foo << bar)
633-
/// return ExprError();
634-
///
635-
/// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably
636-
/// want to use these instead of creating a SemaDiagnosticBuilder yourself.
637-
operator bool() const { return isImmediate(); }
638-
639-
template <typename T>
640-
friend const SemaDiagnosticBuilder &
641-
operator<<(const SemaDiagnosticBuilder &Diag, const T &Value) {
642-
if (Diag.ImmediateDiag)
643-
*Diag.ImmediateDiag << Value;
644-
else if (Diag.PartialDiagId)
645-
Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second
646-
<< Value;
647-
return Diag;
648-
}
649-
650-
// It is necessary to limit this to rvalue reference to avoid calling this
651-
// function with a bitfield lvalue argument since non-const reference to
652-
// bitfield is not allowed.
653-
template <typename T,
654-
typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
655-
const SemaDiagnosticBuilder &operator<<(T &&V) const {
656-
if (ImmediateDiag)
657-
*ImmediateDiag << std::move(V);
658-
else if (PartialDiagId)
659-
S.DeviceDeferredDiags[Fn][*PartialDiagId].second << std::move(V);
660-
return *this;
661-
}
662-
663-
friend const SemaDiagnosticBuilder &
664-
operator<<(const SemaDiagnosticBuilder &Diag, const PartialDiagnostic &PD) {
665-
if (Diag.ImmediateDiag)
666-
PD.Emit(*Diag.ImmediateDiag);
667-
else if (Diag.PartialDiagId)
668-
Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD;
669-
return Diag;
670-
}
671-
672-
void AddFixItHint(const FixItHint &Hint) const {
673-
if (ImmediateDiag)
674-
ImmediateDiag->AddFixItHint(Hint);
675-
else if (PartialDiagId)
676-
S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint);
677-
}
678-
679-
friend ExprResult ExprError(const SemaDiagnosticBuilder &) {
680-
return ExprError();
681-
}
682-
friend StmtResult StmtError(const SemaDiagnosticBuilder &) {
683-
return StmtError();
684-
}
685-
operator ExprResult() const { return ExprError(); }
686-
operator StmtResult() const { return StmtError(); }
687-
operator TypeResult() const { return TypeError(); }
688-
operator DeclResult() const { return DeclResult(true); }
689-
operator MemInitResult() const { return MemInitResult(true); }
690-
691-
private:
692-
Sema &S;
693-
SourceLocation Loc;
694-
unsigned DiagID;
695-
const FunctionDecl *Fn;
696-
bool ShowCallStack;
697-
698-
// Invariant: At most one of these Optionals has a value.
699-
// FIXME: Switch these to a Variant once that exists.
700-
std::optional<ImmediateDiagBuilder> ImmediateDiag;
701-
std::optional<unsigned> PartialDiagId;
702-
};
703-
704516
void PrintStats() const;
705517

706518
/// Warn that the stack is nearly exhausted.
@@ -742,14 +554,6 @@ class Sema final {
742554

743555
void addImplicitTypedef(StringRef Name, QualType T);
744556

745-
/// Emit a diagnostic.
746-
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID,
747-
bool DeferHint = false);
748-
749-
/// Emit a partial diagnostic.
750-
SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic &PD,
751-
bool DeferHint = false);
752-
753557
/// Whether uncompilable error has occurred. This includes error happens
754558
/// in deferred diagnostics.
755559
bool hasUncompilableErrorOccurred() const;
@@ -13119,9 +12923,7 @@ class Sema final {
1311912923
/// Diagnostics that are emitted only if we discover that the given function
1312012924
/// must be codegen'ed. Because handling these correctly adds overhead to
1312112925
/// compilation, this is currently only enabled for CUDA compilations.
13122-
llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
13123-
std::vector<PartialDiagnosticAt>>
13124-
DeviceDeferredDiags;
12926+
SemaDiagnosticBuilder::DeferredDiagnosticsType DeviceDeferredDiags;
1312512927

1312612928
/// A pair of a canonical FunctionDecl and a SourceLocation. When used as the
1312712929
/// key in a hashtable, both the FD and location are hashed.

0 commit comments

Comments
 (0)