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:
John McCall 2010-08-26 02:13:20 +00:00
Родитель faf9404ae2
Коммит 9c3087b0b0
6 изменённых файлов: 193 добавлений и 144 удалений

Просмотреть файл

@ -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;