From 679063472244a6cb6d4b52894ac020022690620d Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 25 Aug 2010 23:44:00 +0000 Subject: [PATCH] Pull DelayedDiagnostic and AccessedEntity out into their own header. This works courtesy of the new SmallVector<..., 0> specialization that doesn't require a complete type. Note that you'll need to pull at least SmallVector.h from LLVM to compile successfully. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112114 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/DelayedDiagnostic.h | 168 +++++++++++++++++++++++++ include/clang/Sema/Sema.h | 142 +-------------------- include/clang/Sema/SemaInternal.h | 9 ++ lib/Sema/Sema.cpp | 4 +- lib/Sema/SemaAccess.cpp | 10 +- lib/Sema/SemaDeclAttr.cpp | 4 +- 6 files changed, 193 insertions(+), 144 deletions(-) create mode 100644 include/clang/Sema/DelayedDiagnostic.h diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h new file mode 100644 index 0000000000..655f8332be --- /dev/null +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -0,0 +1,168 @@ +//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the DelayedDiagnostic class, which is used to +// record diagnostics that are being conditionally produced during +// declarator parsing. Certain kinds of diagnostics --- notably +// deprecation and access control --- are suppressed based on +// semantic properties of the parsed declaration that aren't known +// until it is fully parsed. +// +// This file also defines AccessedEntity. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H +#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H + +#include "clang/AST/DeclCXX.h" + +namespace clang { +namespace sema { + +/// A declaration being accessed, together with information about how +/// it was accessed. +class AccessedEntity { +public: + /// A member declaration found through lookup. The target is the + /// member. + enum MemberNonce { Member }; + + /// A hierarchy (base-to-derived or derived-to-base) conversion. + /// The target is the base class. + enum BaseNonce { Base }; + + bool isMemberAccess() const { return IsMember; } + + AccessedEntity(ASTContext &Context, + MemberNonce _, + CXXRecordDecl *NamingClass, + DeclAccessPair FoundDecl, + QualType BaseObjectType) + : Access(FoundDecl.getAccess()), IsMember(true), + Target(FoundDecl.getDecl()), NamingClass(NamingClass), + BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) { + } + + AccessedEntity(ASTContext &Context, + BaseNonce _, + CXXRecordDecl *BaseClass, + CXXRecordDecl *DerivedClass, + AccessSpecifier Access) + : Access(Access), IsMember(false), + Target(reinterpret_cast(BaseClass)), + NamingClass(DerivedClass), + Diag(0, Context.getDiagAllocator()) { + } + + bool isQuiet() const { return Diag.getDiagID() == 0; } + + AccessSpecifier getAccess() const { return AccessSpecifier(Access); } + + // These apply to member decls... + NamedDecl *getTargetDecl() const { return Target; } + CXXRecordDecl *getNamingClass() const { return NamingClass; } + + // ...and these apply to hierarchy conversions. + CXXRecordDecl *getBaseClass() const { + assert(!IsMember); return reinterpret_cast(Target); + } + CXXRecordDecl *getDerivedClass() const { return NamingClass; } + + /// Retrieves the base object type, important when accessing + /// an instance member. + QualType getBaseObjectType() const { return BaseObjectType; } + + /// Sets a diagnostic to be performed. The diagnostic is given + /// four (additional) arguments: + /// %0 - 0 if the entity was private, 1 if protected + /// %1 - the DeclarationName of the entity + /// %2 - the TypeDecl type of the naming class + /// %3 - the TypeDecl type of the declaring class + void setDiag(const PartialDiagnostic &PDiag) { + assert(isQuiet() && "partial diagnostic already defined"); + Diag = PDiag; + } + PartialDiagnostic &setDiag(unsigned DiagID) { + assert(isQuiet() && "partial diagnostic already defined"); + assert(DiagID && "creating null diagnostic"); + Diag.Reset(DiagID); + return Diag; + } + const PartialDiagnostic &getDiag() const { + return Diag; + } + +private: + unsigned Access : 2; + bool IsMember; + NamedDecl *Target; + CXXRecordDecl *NamingClass; + QualType BaseObjectType; + PartialDiagnostic Diag; +}; + +/// A diagnostic message which has been conditionally emitted pending +/// the complete parsing of the current declaration. +class DelayedDiagnostic { +public: + enum DDKind { Deprecation, Access }; + + unsigned char Kind; // actually a DDKind + bool Triggered; + + SourceLocation Loc; + + union { + /// Deprecation. + struct { NamedDecl *Decl; } DeprecationData; + + /// Access control. + char AccessData[sizeof(AccessedEntity)]; + }; + + void destroy() { + switch (Kind) { + case Access: getAccessData().~AccessedEntity(); break; + case Deprecation: break; + } + } + + static DelayedDiagnostic makeDeprecation(SourceLocation Loc, + NamedDecl *D) { + DelayedDiagnostic DD; + DD.Kind = Deprecation; + DD.Triggered = false; + DD.Loc = Loc; + DD.DeprecationData.Decl = D; + return DD; + } + + static DelayedDiagnostic makeAccess(SourceLocation Loc, + const AccessedEntity &Entity) { + DelayedDiagnostic DD; + DD.Kind = Access; + DD.Triggered = false; + DD.Loc = Loc; + new (&DD.getAccessData()) AccessedEntity(Entity); + return DD; + } + + AccessedEntity &getAccessData() { + return *reinterpret_cast(AccessData); + } + const AccessedEntity &getAccessData() const { + return *reinterpret_cast(AccessData); + } +}; + +} +} + +#endif diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4bbc021bcd..e6e97dfed5 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -128,6 +128,7 @@ namespace clang { namespace sema { class AccessedEntity; class BlockScopeInfo; + class DelayedDiagnostic; class FunctionScopeInfo; class TemplateDeductionInfo; } @@ -284,140 +285,9 @@ public: /// and must warn if not used. Only contains the first declaration. llvm::SmallVector UnusedFileScopedDecls; - class AccessedEntity { - public: - /// A member declaration found through lookup. The target is the - /// member. - enum MemberNonce { Member }; - - /// A hierarchy (base-to-derived or derived-to-base) conversion. - /// The target is the base class. - enum BaseNonce { Base }; - - bool isMemberAccess() const { return IsMember; } - - AccessedEntity(ASTContext &Context, - MemberNonce _, - CXXRecordDecl *NamingClass, - DeclAccessPair FoundDecl, - QualType BaseObjectType) - : Access(FoundDecl.getAccess()), IsMember(true), - Target(FoundDecl.getDecl()), NamingClass(NamingClass), - BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) { - } - - AccessedEntity(ASTContext &Context, - BaseNonce _, - CXXRecordDecl *BaseClass, - CXXRecordDecl *DerivedClass, - AccessSpecifier Access) - : Access(Access), IsMember(false), - Target(reinterpret_cast(BaseClass)), - NamingClass(DerivedClass), - Diag(0, Context.getDiagAllocator()) { - } - - bool isQuiet() const { return Diag.getDiagID() == 0; } - - AccessSpecifier getAccess() const { return AccessSpecifier(Access); } - - // These apply to member decls... - NamedDecl *getTargetDecl() const { return Target; } - CXXRecordDecl *getNamingClass() const { return NamingClass; } - - // ...and these apply to hierarchy conversions. - CXXRecordDecl *getBaseClass() const { - assert(!IsMember); return reinterpret_cast(Target); - } - CXXRecordDecl *getDerivedClass() const { return NamingClass; } - - /// Retrieves the base object type, important when accessing - /// an instance member. - QualType getBaseObjectType() const { return BaseObjectType; } - - /// Sets a diagnostic to be performed. The diagnostic is given - /// four (additional) arguments: - /// %0 - 0 if the entity was private, 1 if protected - /// %1 - the DeclarationName of the entity - /// %2 - the TypeDecl type of the naming class - /// %3 - the TypeDecl type of the declaring class - void setDiag(const PartialDiagnostic &PDiag) { - assert(isQuiet() && "partial diagnostic already defined"); - Diag = PDiag; - } - PartialDiagnostic &setDiag(unsigned DiagID) { - assert(isQuiet() && "partial diagnostic already defined"); - assert(DiagID && "creating null diagnostic"); - Diag.Reset(DiagID); - return Diag; - } - const PartialDiagnostic &getDiag() const { - return Diag; - } - - private: - unsigned Access : 2; - bool IsMember; - NamedDecl *Target; - CXXRecordDecl *NamingClass; - QualType BaseObjectType; - PartialDiagnostic Diag; - }; - - struct DelayedDiagnostic { - enum DDKind { Deprecation, Access }; - - unsigned char Kind; // actually a DDKind - bool Triggered; - - SourceLocation Loc; - - union { - /// Deprecation. - struct { NamedDecl *Decl; } DeprecationData; - - /// Access control. - char AccessData[sizeof(AccessedEntity)]; - }; - - void destroy() { - switch (Kind) { - case Access: getAccessData().~AccessedEntity(); break; - case Deprecation: break; - } - } - - static DelayedDiagnostic makeDeprecation(SourceLocation Loc, - NamedDecl *D) { - DelayedDiagnostic DD; - DD.Kind = Deprecation; - DD.Triggered = false; - DD.Loc = Loc; - DD.DeprecationData.Decl = D; - return DD; - } - - static DelayedDiagnostic makeAccess(SourceLocation Loc, - const AccessedEntity &Entity) { - DelayedDiagnostic DD; - DD.Kind = Access; - DD.Triggered = false; - DD.Loc = Loc; - new (&DD.getAccessData()) AccessedEntity(Entity); - return DD; - } - - AccessedEntity &getAccessData() { - return *reinterpret_cast(AccessData); - } - const AccessedEntity &getAccessData() const { - return *reinterpret_cast(AccessData); - } - }; - /// \brief The stack of diagnostics that were delayed due to being /// produced during the parsing of a declaration. - llvm::SmallVector DelayedDiagnostics; + llvm::SmallVector DelayedDiagnostics; /// \brief The depth of the current ParsingDeclaration stack. /// If nonzero, we are currently parsing a declaration (and @@ -614,9 +484,7 @@ public: SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD); /// \brief Build a partial diagnostic. - PartialDiagnostic PDiag(unsigned DiagID = 0) { - return PartialDiagnostic(DiagID, Context.getDiagAllocator()); - } + PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h virtual void DeleteExpr(ExprTy *E); virtual void DeleteStmt(StmtTy *S); @@ -1701,7 +1569,7 @@ public: void PopParsingDeclaration(ParsingDeclStackState S, Decl *D); void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc); - void HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, Decl *Ctx); + void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. @@ -2747,7 +2615,7 @@ public: void PerformDependentDiagnostics(const DeclContext *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs); - void HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx); + void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); /// A flag to suppress access checking. bool SuppressAccessChecking; diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index 1871350deb..64b83e3bf6 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -17,5 +17,14 @@ #include "clang/Sema/Sema.h" #include "clang/Sema/SemaDiagnostic.h" +#include "clang/AST/ASTContext.h" + +namespace clang { + +inline PartialDiagnostic Sema::PDiag(unsigned DiagID) { + return PartialDiagnostic(DiagID, Context.getDiagAllocator()); +} + +} #endif diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index fd6dcfc095..2de4d28cab 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/Sema.h" -#include "clang/Sema/SemaDiagnostic.h" +#include "clang/Sema/SemaInternal.h" +#include "clang/Sema/DelayedDiagnostic.h" #include "TargetAttributesSema.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 965ec66a13..7cda7dd172 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/AST/ASTContext.h" @@ -22,6 +23,7 @@ #include "clang/AST/ExprCXX.h" using namespace clang; +using namespace sema; /// A copy of Sema's enum without AR_delayed. enum AccessResult { @@ -132,10 +134,10 @@ struct EffectiveContext { bool Dependent; }; -/// Like Sema's AccessedEntity, but kindly lets us scribble all over +/// Like sema:;AccessedEntity, but kindly lets us scribble all over /// it. -struct AccessTarget : public Sema::AccessedEntity { - AccessTarget(const Sema::AccessedEntity &Entity) +struct AccessTarget : public AccessedEntity { + AccessTarget(const AccessedEntity &Entity) : AccessedEntity(Entity) { initialize(); } @@ -1033,7 +1035,7 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, // access control. if (S.CurContext->isFileContext() && S.ParsingDeclDepth) { S.DelayedDiagnostics.push_back( - Sema::DelayedDiagnostic::makeAccess(Loc, Entity)); + DelayedDiagnostic::makeAccess(Loc, Entity)); return Sema::AR_delayed; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index a2cad6a5d2..46623d2818 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -19,8 +19,10 @@ #include "clang/AST/Expr.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/DelayedDiagnostic.h" #include "llvm/ADT/StringExtras.h" using namespace clang; +using namespace sema; //===----------------------------------------------------------------------===// // Helper functions @@ -2468,7 +2470,7 @@ static bool isDeclDeprecated(Decl *D) { return false; } -void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, +void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, Decl *Ctx) { if (isDeclDeprecated(Ctx)) return; -- 2.40.0