зеркало из https://github.com/microsoft/clang-1.git
Restore r112114 now that SmallVector<...,0> is safe.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112148 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
faf9404ae2
Коммит
9c3087b0b0
|
@ -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<NamedDecl*>(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<CXXRecordDecl*>(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<AccessedEntity*>(AccessData);
|
||||
}
|
||||
const AccessedEntity &getAccessData() const {
|
||||
return *reinterpret_cast<const AccessedEntity*>(AccessData);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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<const DeclaratorDecl*, 4> 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<NamedDecl*>(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<CXXRecordDecl*>(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<AccessedEntity*>(AccessData);
|
||||
}
|
||||
const AccessedEntity &getAccessData() const {
|
||||
return *reinterpret_cast<const AccessedEntity*>(AccessData);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief The stack of diagnostics that were delayed due to being
|
||||
/// produced during the parsing of a declaration.
|
||||
llvm::SmallVector<DelayedDiagnostic, 8> DelayedDiagnostics;
|
||||
llvm::SmallVector<sema::DelayedDiagnostic, 0> 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче