Remove FileVarDecl and BlockVarDecl. They are replaced by VarDecl::isBlockVarDecl() and VarDecl::isFileVarDecl().
This is a fairly mechanical/large change. As a result, I avoided making any changes/simplifications that weren't directly related. I did break two Analysis tests. I also have a couple FIXME's in UninitializedValues.cpp. Ted, can you take a look? If the bug isn't obvious, I am happy to dig in and fix it (since I broke it). llvm-svn: 49748
This commit is contained in:
parent
82b6673c44
commit
08899ff85d
|
@ -70,7 +70,7 @@ namespace {
|
||||||
FunctionDecl *SuperContructorFunctionDecl;
|
FunctionDecl *SuperContructorFunctionDecl;
|
||||||
|
|
||||||
// ObjC string constant support.
|
// ObjC string constant support.
|
||||||
FileVarDecl *ConstantStringClassReference;
|
VarDecl *ConstantStringClassReference;
|
||||||
RecordDecl *NSStringRecord;
|
RecordDecl *NSStringRecord;
|
||||||
|
|
||||||
// ObjC foreach break/continue generation support.
|
// ObjC foreach break/continue generation support.
|
||||||
|
@ -367,7 +367,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) {
|
||||||
// Look for built-in declarations that we need to refer during the rewrite.
|
// Look for built-in declarations that we need to refer during the rewrite.
|
||||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||||
RewriteFunctionDecl(FD);
|
RewriteFunctionDecl(FD);
|
||||||
} else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
|
} else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
|
||||||
// declared in <Foundation/NSString.h>
|
// declared in <Foundation/NSString.h>
|
||||||
if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) {
|
if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) {
|
||||||
ConstantStringClassReference = FVD;
|
ConstantStringClassReference = FVD;
|
||||||
|
@ -1776,9 +1776,9 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
|
||||||
// The minus 2 removes the begin/end double quotes.
|
// The minus 2 removes the begin/end double quotes.
|
||||||
Preamble += utostr(prettyBuf.str().size()-2) + "};\n";
|
Preamble += utostr(prettyBuf.str().size()-2) + "};\n";
|
||||||
|
|
||||||
FileVarDecl *NewVD = FileVarDecl::Create(*Context, NULL, SourceLocation(),
|
VarDecl *NewVD = VarDecl::Create(*Context, NULL, SourceLocation(),
|
||||||
&Context->Idents.get(S.c_str()), strType,
|
&Context->Idents.get(S.c_str()), strType,
|
||||||
VarDecl::Static, NULL);
|
VarDecl::Static, NULL);
|
||||||
DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation());
|
DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation());
|
||||||
Expr *Unop = new UnaryOperator(DRE, UnaryOperator::AddrOf,
|
Expr *Unop = new UnaryOperator(DRE, UnaryOperator::AddrOf,
|
||||||
Context->getPointerType(DRE->getType()),
|
Context->getPointerType(DRE->getType()),
|
||||||
|
|
|
@ -146,6 +146,10 @@ protected:
|
||||||
StorageClass SC, ScopedDecl *PrevDecl)
|
StorageClass SC, ScopedDecl *PrevDecl)
|
||||||
: ValueDecl(DK, CD, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
|
: ValueDecl(DK, CD, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
|
||||||
public:
|
public:
|
||||||
|
static VarDecl *Create(ASTContext &C, DeclContext *CD,
|
||||||
|
SourceLocation L, IdentifierInfo *Id,
|
||||||
|
QualType T, StorageClass S, ScopedDecl *PrevDecl);
|
||||||
|
|
||||||
StorageClass getStorageClass() const { return (StorageClass)SClass; }
|
StorageClass getStorageClass() const { return (StorageClass)SClass; }
|
||||||
|
|
||||||
const Expr *getInit() const { return Init; }
|
const Expr *getInit() const { return Init; }
|
||||||
|
@ -156,7 +160,7 @@ public:
|
||||||
/// is a non-static local variable.
|
/// is a non-static local variable.
|
||||||
bool hasLocalStorage() const {
|
bool hasLocalStorage() const {
|
||||||
if (getStorageClass() == None)
|
if (getStorageClass() == None)
|
||||||
return getKind() != FileVar;
|
return !isFileVarDecl();
|
||||||
|
|
||||||
// Return true for: Auto, Register.
|
// Return true for: Auto, Register.
|
||||||
// Return false for: Extern, Static, PrivateExtern.
|
// Return false for: Extern, Static, PrivateExtern.
|
||||||
|
@ -169,6 +173,29 @@ public:
|
||||||
/// as static variables declared within a function.
|
/// as static variables declared within a function.
|
||||||
bool hasGlobalStorage() const { return !hasLocalStorage(); }
|
bool hasGlobalStorage() const { return !hasLocalStorage(); }
|
||||||
|
|
||||||
|
/// isBlockVarDecl - Returns true for local variable declarations. Note that
|
||||||
|
/// this includes static variables inside of functions.
|
||||||
|
///
|
||||||
|
/// void foo() { int x; static int y; extern int z; }
|
||||||
|
///
|
||||||
|
bool isBlockVarDecl() const {
|
||||||
|
if (getKind() != Decl::Var)
|
||||||
|
return false;
|
||||||
|
if (DeclContext *DC = getDeclContext())
|
||||||
|
return DC->isFunctionOrMethod();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// isFileVarDecl - Returns true for file scoped variable declaration.
|
||||||
|
bool isFileVarDecl() const {
|
||||||
|
if (getKind() != Decl::Var)
|
||||||
|
return false;
|
||||||
|
// FIXME: change when TranlationUnitDecl is added as a declaration context.
|
||||||
|
if (!getDeclContext())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
static bool classof(const Decl *D) {
|
static bool classof(const Decl *D) {
|
||||||
return D->getKind() >= VarFirst && D->getKind() <= VarLast;
|
return D->getKind() >= VarFirst && D->getKind() <= VarLast;
|
||||||
|
@ -187,56 +214,9 @@ protected:
|
||||||
|
|
||||||
/// ReadImpl - Deserialize this VarDecl. Called by subclasses.
|
/// ReadImpl - Deserialize this VarDecl. Called by subclasses.
|
||||||
virtual void ReadImpl(llvm::Deserializer& D, ASTContext& C);
|
virtual void ReadImpl(llvm::Deserializer& D, ASTContext& C);
|
||||||
};
|
|
||||||
|
|
||||||
/// BlockVarDecl - Represent a local variable declaration. Note that this
|
/// CreateImpl - Deserialize a VarDecl. Called by Decl::Create.
|
||||||
/// includes static variables inside of functions.
|
static VarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
||||||
///
|
|
||||||
/// void foo() { int x; static int y; extern int z; }
|
|
||||||
///
|
|
||||||
class BlockVarDecl : public VarDecl {
|
|
||||||
BlockVarDecl(DeclContext *CD, SourceLocation L,
|
|
||||||
IdentifierInfo *Id, QualType T, StorageClass S,
|
|
||||||
ScopedDecl *PrevDecl)
|
|
||||||
: VarDecl(BlockVar, CD, L, Id, T, S, PrevDecl) {}
|
|
||||||
public:
|
|
||||||
static BlockVarDecl *Create(ASTContext &C, DeclContext *CD, SourceLocation L,
|
|
||||||
IdentifierInfo *Id, QualType T, StorageClass S,
|
|
||||||
ScopedDecl *PrevDecl);
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
|
||||||
static bool classof(const Decl *D) { return D->getKind() == BlockVar; }
|
|
||||||
static bool classof(const BlockVarDecl *D) { return true; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// CreateImpl - Deserialize a BlockVarDecl. Called by Decl::Create.
|
|
||||||
static BlockVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
|
||||||
|
|
||||||
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// FileVarDecl - Represent a file scoped variable declaration. This
|
|
||||||
/// will allow us to reason about external variable declarations and tentative
|
|
||||||
/// definitions (C99 6.9.2p2) using our type system (without storing a
|
|
||||||
/// pointer to the decl's scope, which is transient).
|
|
||||||
class FileVarDecl : public VarDecl {
|
|
||||||
FileVarDecl(DeclContext *CD, SourceLocation L,
|
|
||||||
IdentifierInfo *Id, QualType T, StorageClass S,
|
|
||||||
ScopedDecl *PrevDecl)
|
|
||||||
: VarDecl(FileVar, CD, L, Id, T, S, PrevDecl) {}
|
|
||||||
public:
|
|
||||||
static FileVarDecl *Create(ASTContext &C, DeclContext *CD,
|
|
||||||
SourceLocation L, IdentifierInfo *Id,
|
|
||||||
QualType T, StorageClass S, ScopedDecl *PrevDecl);
|
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
|
||||||
static bool classof(const Decl *D) { return D->getKind() == FileVar; }
|
|
||||||
static bool classof(const FileVarDecl *D) { return true; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// CreateImpl - Deserialize a FileVarDecl. Called by Decl::Create.
|
|
||||||
static FileVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
|
||||||
|
|
||||||
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ParmVarDecl - Represent a parameter to a function.
|
/// ParmVarDecl - Represent a parameter to a function.
|
||||||
|
|
|
@ -55,9 +55,7 @@ public:
|
||||||
// ValueDecl
|
// ValueDecl
|
||||||
EnumConstant,
|
EnumConstant,
|
||||||
Function,
|
Function,
|
||||||
// VarDecl
|
Var,
|
||||||
BlockVar,
|
|
||||||
FileVar,
|
|
||||||
ParmVar,
|
ParmVar,
|
||||||
ObjCInterface,
|
ObjCInterface,
|
||||||
ObjCCompatibleAlias,
|
ObjCCompatibleAlias,
|
||||||
|
@ -76,7 +74,7 @@ public:
|
||||||
TagFirst = Enum , TagLast = Class,
|
TagFirst = Enum , TagLast = Class,
|
||||||
RecordFirst = Struct , RecordLast = Class,
|
RecordFirst = Struct , RecordLast = Class,
|
||||||
ValueFirst = EnumConstant , ValueLast = ParmVar,
|
ValueFirst = EnumConstant , ValueLast = ParmVar,
|
||||||
VarFirst = BlockVar , VarLast = ParmVar
|
VarFirst = Var , VarLast = ParmVar
|
||||||
};
|
};
|
||||||
|
|
||||||
/// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
|
/// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
|
||||||
|
@ -151,8 +149,7 @@ public:
|
||||||
default: assert(0 && "Unknown decl kind!");
|
default: assert(0 && "Unknown decl kind!");
|
||||||
case Typedef:
|
case Typedef:
|
||||||
case Function:
|
case Function:
|
||||||
case BlockVar:
|
case Var:
|
||||||
case FileVar:
|
|
||||||
case ParmVar:
|
case ParmVar:
|
||||||
case EnumConstant:
|
case EnumConstant:
|
||||||
case ObjCInterface:
|
case ObjCInterface:
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
struct ObserverTy {
|
struct ObserverTy {
|
||||||
virtual ~ObserverTy();
|
virtual ~ObserverTy();
|
||||||
virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
|
virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
|
||||||
DeclRefExpr* DR, BlockVarDecl* VD) = 0;
|
DeclRefExpr* DR, VarDecl* VD) = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,7 @@ public:
|
||||||
void VisitScopedDecl(ScopedDecl* D) {
|
void VisitScopedDecl(ScopedDecl* D) {
|
||||||
switch (D->getKind()) {
|
switch (D->getKind()) {
|
||||||
DISPATCH_CASE(Function,FunctionDecl)
|
DISPATCH_CASE(Function,FunctionDecl)
|
||||||
DISPATCH_CASE(BlockVar,BlockVarDecl) // FIXME:Refine. VisitVarDecl?
|
DISPATCH_CASE(Var,VarDecl)
|
||||||
DISPATCH_CASE(FileVar,FileVarDecl) // FIXME: (same)
|
|
||||||
DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
|
DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
|
||||||
DISPATCH_CASE(EnumConstant,EnumConstantDecl)
|
DISPATCH_CASE(EnumConstant,EnumConstantDecl)
|
||||||
DISPATCH_CASE(Typedef,TypedefDecl)
|
DISPATCH_CASE(Typedef,TypedefDecl)
|
||||||
|
@ -70,8 +69,6 @@ public:
|
||||||
|
|
||||||
DEFAULT_DISPATCH(VarDecl)
|
DEFAULT_DISPATCH(VarDecl)
|
||||||
DEFAULT_DISPATCH(FunctionDecl)
|
DEFAULT_DISPATCH(FunctionDecl)
|
||||||
DEFAULT_DISPATCH_VARDECL(BlockVarDecl)
|
|
||||||
DEFAULT_DISPATCH_VARDECL(FileVarDecl)
|
|
||||||
DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
|
DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
|
||||||
DEFAULT_DISPATCH(EnumConstantDecl)
|
DEFAULT_DISPATCH(EnumConstantDecl)
|
||||||
DEFAULT_DISPATCH(TypedefDecl)
|
DEFAULT_DISPATCH(TypedefDecl)
|
||||||
|
|
|
@ -24,8 +24,7 @@ using namespace clang;
|
||||||
|
|
||||||
// temporary statistics gathering
|
// temporary statistics gathering
|
||||||
static unsigned nFuncs = 0;
|
static unsigned nFuncs = 0;
|
||||||
static unsigned nBlockVars = 0;
|
static unsigned nVars = 0;
|
||||||
static unsigned nFileVars = 0;
|
|
||||||
static unsigned nParmVars = 0;
|
static unsigned nParmVars = 0;
|
||||||
static unsigned nSUC = 0;
|
static unsigned nSUC = 0;
|
||||||
static unsigned nEnumConst = 0;
|
static unsigned nEnumConst = 0;
|
||||||
|
@ -59,8 +58,7 @@ const char *Decl::getDeclKindName() const {
|
||||||
default: assert(0 && "Unknown decl kind!");
|
default: assert(0 && "Unknown decl kind!");
|
||||||
case Typedef: return "Typedef";
|
case Typedef: return "Typedef";
|
||||||
case Function: return "Function";
|
case Function: return "Function";
|
||||||
case BlockVar: return "BlockVar";
|
case Var: return "Var";
|
||||||
case FileVar: return "FileVar";
|
|
||||||
case ParmVar: return "ParmVar";
|
case ParmVar: return "ParmVar";
|
||||||
case EnumConstant: return "EnumConstant";
|
case EnumConstant: return "EnumConstant";
|
||||||
case ObjCInterface: return "ObjCInterface";
|
case ObjCInterface: return "ObjCInterface";
|
||||||
|
@ -84,17 +82,14 @@ bool Decl::CollectingStats(bool Enable) {
|
||||||
void Decl::PrintStats() {
|
void Decl::PrintStats() {
|
||||||
fprintf(stderr, "*** Decl Stats:\n");
|
fprintf(stderr, "*** Decl Stats:\n");
|
||||||
fprintf(stderr, " %d decls total.\n",
|
fprintf(stderr, " %d decls total.\n",
|
||||||
int(nFuncs+nBlockVars+nFileVars+nParmVars+nFieldDecls+nSUC+
|
int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+
|
||||||
nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
|
nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
|
||||||
nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls));
|
nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls));
|
||||||
fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
|
fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
|
||||||
nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
|
nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
|
||||||
fprintf(stderr, " %d block variable decls, %d each (%d bytes)\n",
|
fprintf(stderr, " %d variable decls, %d each (%d bytes)\n",
|
||||||
nBlockVars, (int)sizeof(BlockVarDecl),
|
nVars, (int)sizeof(VarDecl),
|
||||||
int(nBlockVars*sizeof(BlockVarDecl)));
|
int(nVars*sizeof(VarDecl)));
|
||||||
fprintf(stderr, " %d file variable decls, %d each (%d bytes)\n",
|
|
||||||
nFileVars, (int)sizeof(FileVarDecl),
|
|
||||||
int(nFileVars*sizeof(FileVarDecl)));
|
|
||||||
fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
|
fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
|
||||||
nParmVars, (int)sizeof(ParmVarDecl),
|
nParmVars, (int)sizeof(ParmVarDecl),
|
||||||
int(nParmVars*sizeof(ParmVarDecl)));
|
int(nParmVars*sizeof(ParmVarDecl)));
|
||||||
|
@ -152,8 +147,8 @@ void Decl::PrintStats() {
|
||||||
int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
|
int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
|
||||||
|
|
||||||
fprintf(stderr, "Total bytes = %d\n",
|
fprintf(stderr, "Total bytes = %d\n",
|
||||||
int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
|
int(nFuncs*sizeof(FunctionDecl)+
|
||||||
nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
|
nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
|
||||||
nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
|
nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
|
||||||
nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
|
nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
|
||||||
nTypedef*sizeof(TypedefDecl)+
|
nTypedef*sizeof(TypedefDecl)+
|
||||||
|
@ -177,8 +172,7 @@ void Decl::addDeclKind(Kind k) {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case Typedef: nTypedef++; break;
|
case Typedef: nTypedef++; break;
|
||||||
case Function: nFuncs++; break;
|
case Function: nFuncs++; break;
|
||||||
case BlockVar: nBlockVars++; break;
|
case Var: nVars++; break;
|
||||||
case FileVar: nFileVars++; break;
|
|
||||||
case ParmVar: nParmVars++; break;
|
case ParmVar: nParmVars++; break;
|
||||||
case EnumConstant: nEnumConst++; break;
|
case EnumConstant: nEnumConst++; break;
|
||||||
case Field: nFieldDecls++; break;
|
case Field: nFieldDecls++; break;
|
||||||
|
@ -204,23 +198,15 @@ void Decl::addDeclKind(Kind k) {
|
||||||
// Decl Allocation/Deallocation Method Implementations
|
// Decl Allocation/Deallocation Method Implementations
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
BlockVarDecl *BlockVarDecl::Create(ASTContext &C, DeclContext *CD,
|
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *CD,
|
||||||
SourceLocation L,
|
SourceLocation L,
|
||||||
IdentifierInfo *Id, QualType T,
|
IdentifierInfo *Id, QualType T,
|
||||||
StorageClass S, ScopedDecl *PrevDecl) {
|
StorageClass S, ScopedDecl *PrevDecl) {
|
||||||
void *Mem = C.getAllocator().Allocate<BlockVarDecl>();
|
void *Mem = C.getAllocator().Allocate<VarDecl>();
|
||||||
return new (Mem) BlockVarDecl(CD, L, Id, T, S, PrevDecl);
|
return new (Mem) VarDecl(Var, CD, L, Id, T, S, PrevDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FileVarDecl *FileVarDecl::Create(ASTContext &C, DeclContext *CD,
|
|
||||||
SourceLocation L, IdentifierInfo *Id,
|
|
||||||
QualType T, StorageClass S,
|
|
||||||
ScopedDecl *PrevDecl) {
|
|
||||||
void *Mem = C.getAllocator().Allocate<FileVarDecl>();
|
|
||||||
return new (Mem) FileVarDecl(CD, L, Id, T, S, PrevDecl);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *CD,
|
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *CD,
|
||||||
SourceLocation L, IdentifierInfo *Id,
|
SourceLocation L, IdentifierInfo *Id,
|
||||||
QualType T, StorageClass S,
|
QualType T, StorageClass S,
|
||||||
|
@ -347,8 +333,7 @@ void Decl::Destroy(ASTContext& C) const {
|
||||||
CASE(Enum);
|
CASE(Enum);
|
||||||
CASE(EnumConstant);
|
CASE(EnumConstant);
|
||||||
CASE(Function);
|
CASE(Function);
|
||||||
CASE(BlockVar);
|
CASE(Var);
|
||||||
CASE(FileVar);
|
|
||||||
CASE(ParmVar);
|
CASE(ParmVar);
|
||||||
CASE(ObjCInterface);
|
CASE(ObjCInterface);
|
||||||
CASE(ObjCCompatibleAlias);
|
CASE(ObjCCompatibleAlias);
|
||||||
|
|
|
@ -41,8 +41,8 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) {
|
||||||
assert (false && "Not implemented.");
|
assert (false && "Not implemented.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BlockVar:
|
case Var:
|
||||||
return BlockVarDecl::CreateImpl(D, C);
|
return VarDecl::CreateImpl(D, C);
|
||||||
|
|
||||||
case Enum:
|
case Enum:
|
||||||
return EnumDecl::CreateImpl(D, C);
|
return EnumDecl::CreateImpl(D, C);
|
||||||
|
@ -53,9 +53,6 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) {
|
||||||
case Field:
|
case Field:
|
||||||
return FieldDecl::CreateImpl(D, C);
|
return FieldDecl::CreateImpl(D, C);
|
||||||
|
|
||||||
case FileVar:
|
|
||||||
return FileVarDecl::CreateImpl(D, C);
|
|
||||||
|
|
||||||
case ParmVar:
|
case ParmVar:
|
||||||
return ParmVarDecl::CreateImpl(D, C);
|
return ParmVarDecl::CreateImpl(D, C);
|
||||||
|
|
||||||
|
@ -195,13 +192,13 @@ void VarDecl::ReadImpl(Deserializer& D, ASTContext& C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// BlockVarDecl Serialization.
|
// VarDecl Serialization.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
VarDecl* VarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||||
void *Mem = C.getAllocator().Allocate<BlockVarDecl>();
|
void *Mem = C.getAllocator().Allocate<VarDecl>();
|
||||||
BlockVarDecl* decl =
|
VarDecl* decl =
|
||||||
new (Mem) BlockVarDecl(0, SourceLocation(), NULL, QualType(), None, NULL);
|
new (Mem) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None, NULL);
|
||||||
|
|
||||||
decl->VarDecl::ReadImpl(D, C);
|
decl->VarDecl::ReadImpl(D, C);
|
||||||
|
|
||||||
|
@ -209,21 +206,7 @@ BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// FileVarDecl Serialization.
|
// ParmVarDecl Serialization.
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
|
||||||
void *Mem = C.getAllocator().Allocate<FileVarDecl>();
|
|
||||||
FileVarDecl* decl =
|
|
||||||
new (Mem) FileVarDecl(0, SourceLocation(), NULL, QualType(), None, NULL);
|
|
||||||
|
|
||||||
decl->VarDecl::ReadImpl(D, C);
|
|
||||||
|
|
||||||
return decl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// ParmDecl Serialization.
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
|
void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
|
||||||
|
|
|
@ -280,8 +280,7 @@ void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
|
||||||
fprintf(F, " ");
|
fprintf(F, " ");
|
||||||
switch (Node->getDecl()->getKind()) {
|
switch (Node->getDecl()->getKind()) {
|
||||||
case Decl::Function: fprintf(F,"FunctionDecl"); break;
|
case Decl::Function: fprintf(F,"FunctionDecl"); break;
|
||||||
case Decl::BlockVar: fprintf(F,"BlockVar"); break;
|
case Decl::Var: fprintf(F,"Var"); break;
|
||||||
case Decl::FileVar: fprintf(F,"FileVar"); break;
|
|
||||||
case Decl::ParmVar: fprintf(F,"ParmVar"); break;
|
case Decl::ParmVar: fprintf(F,"ParmVar"); break;
|
||||||
case Decl::EnumConstant: fprintf(F,"EnumConstant"); break;
|
case Decl::EnumConstant: fprintf(F,"EnumConstant"); break;
|
||||||
case Decl::Typedef: fprintf(F,"Typedef"); break;
|
case Decl::Typedef: fprintf(F,"Typedef"); break;
|
||||||
|
|
|
@ -738,7 +738,7 @@ void GRExprEngine::VisitDeclStmt(DeclStmt* DS, GRExprEngine::NodeTy* Pred,
|
||||||
// In this context, Static => Local variable.
|
// In this context, Static => Local variable.
|
||||||
|
|
||||||
assert (!VD->getStorageClass() == VarDecl::Static ||
|
assert (!VD->getStorageClass() == VarDecl::Static ||
|
||||||
!isa<FileVarDecl>(VD));
|
!VD->isFileVarDecl());
|
||||||
|
|
||||||
// If there is no initializer, set the value of the
|
// If there is no initializer, set the value of the
|
||||||
// variable to "Undefined".
|
// variable to "Undefined".
|
||||||
|
|
|
@ -36,7 +36,7 @@ class VISIBILITY_HIDDEN RegisterDecls
|
||||||
public:
|
public:
|
||||||
RegisterDecls(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
|
RegisterDecls(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
|
||||||
|
|
||||||
void VisitBlockVarDecl(BlockVarDecl* VD) { AD.Register(VD); }
|
void VisitBlockVarDecl(VarDecl* VD) { AD.Register(VD); }
|
||||||
CFG& getCFG() { return AD.getCFG(); }
|
CFG& getCFG() { return AD.getCFG(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,14 +80,16 @@ public:
|
||||||
|
|
||||||
void VisitTerminator(Stmt* T) { }
|
void VisitTerminator(Stmt* T) { }
|
||||||
|
|
||||||
BlockVarDecl* FindBlockVarDecl(Stmt* S);
|
VarDecl* FindBlockVarDecl(Stmt* S);
|
||||||
};
|
};
|
||||||
|
|
||||||
static const bool Initialized = true;
|
static const bool Initialized = true;
|
||||||
static const bool Uninitialized = false;
|
static const bool Uninitialized = false;
|
||||||
|
|
||||||
bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
|
bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
|
||||||
if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
|
// FIXME: Ted, can this be simplified?
|
||||||
|
VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl());
|
||||||
|
if (VD && VD->isBlockVarDecl()) {
|
||||||
if (AD.Observer) AD.Observer->ObserveDeclRefExpr(V,AD,DR,VD);
|
if (AD.Observer) AD.Observer->ObserveDeclRefExpr(V,AD,DR,VD);
|
||||||
|
|
||||||
// Pseudo-hack to prevent cascade of warnings. If an accessed variable
|
// Pseudo-hack to prevent cascade of warnings. If an accessed variable
|
||||||
|
@ -101,13 +103,15 @@ bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
|
||||||
else return Initialized;
|
else return Initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockVarDecl* TransferFuncs::FindBlockVarDecl(Stmt *S) {
|
VarDecl* TransferFuncs::FindBlockVarDecl(Stmt *S) {
|
||||||
for (;;)
|
for (;;)
|
||||||
if (ParenExpr* P = dyn_cast<ParenExpr>(S)) {
|
if (ParenExpr* P = dyn_cast<ParenExpr>(S)) {
|
||||||
S = P->getSubExpr(); continue;
|
S = P->getSubExpr(); continue;
|
||||||
}
|
}
|
||||||
else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
|
else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
|
||||||
if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl()))
|
// FIXME: Ted, can this be simplified?
|
||||||
|
VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl());
|
||||||
|
if (VD->isBlockVarDecl())
|
||||||
return VD;
|
return VD;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -116,7 +120,9 @@ BlockVarDecl* TransferFuncs::FindBlockVarDecl(Stmt *S) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
|
bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
|
||||||
if (BlockVarDecl* VD = FindBlockVarDecl(B->getLHS()))
|
// FIXME: Ted, can this be simplified?
|
||||||
|
VarDecl* VD = FindBlockVarDecl(B->getLHS());
|
||||||
|
if (VD && VD->isBlockVarDecl())
|
||||||
if (B->isAssignmentOp()) {
|
if (B->isAssignmentOp()) {
|
||||||
if (B->getOpcode() == BinaryOperator::Assign)
|
if (B->getOpcode() == BinaryOperator::Assign)
|
||||||
return V(VD,AD) = Visit(B->getRHS());
|
return V(VD,AD) = Visit(B->getRHS());
|
||||||
|
@ -128,8 +134,9 @@ bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
|
bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
|
||||||
for (ScopedDecl* D = S->getDecl(); D != NULL; D = D->getNextDeclarator())
|
for (ScopedDecl* D = S->getDecl(); D != NULL; D = D->getNextDeclarator()) {
|
||||||
if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(D)) {
|
VarDecl *VD = dyn_cast<VarDecl>(D);
|
||||||
|
if (VD && VD->isBlockVarDecl()) {
|
||||||
if (Stmt* I = VD->getInit())
|
if (Stmt* I = VD->getInit())
|
||||||
V(VD,AD) = AD.FullUninitTaint ? V(cast<Expr>(I),AD) : Initialized;
|
V(VD,AD) = AD.FullUninitTaint ? V(cast<Expr>(I),AD) : Initialized;
|
||||||
else {
|
else {
|
||||||
|
@ -149,7 +156,7 @@ bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
|
||||||
V(VD,AD) = Uninitialized;
|
V(VD,AD) = Uninitialized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Uninitialized; // Value is never consumed.
|
return Uninitialized; // Value is never consumed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +168,9 @@ bool TransferFuncs::VisitCallExpr(CallExpr* C) {
|
||||||
bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
|
bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
|
||||||
switch (U->getOpcode()) {
|
switch (U->getOpcode()) {
|
||||||
case UnaryOperator::AddrOf:
|
case UnaryOperator::AddrOf:
|
||||||
if (BlockVarDecl* VD = FindBlockVarDecl(U->getSubExpr()))
|
VarDecl* VD = FindBlockVarDecl(U->getSubExpr());
|
||||||
|
if (VD && VD->isBlockVarDecl())
|
||||||
return V(VD,AD) = Initialized;
|
return V(VD,AD) = Initialized;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UnaryOperator::SizeOf:
|
case UnaryOperator::SizeOf:
|
||||||
|
@ -240,7 +247,7 @@ class VISIBILITY_HIDDEN UninitializedValuesChecker
|
||||||
|
|
||||||
ASTContext &Ctx;
|
ASTContext &Ctx;
|
||||||
Diagnostic &Diags;
|
Diagnostic &Diags;
|
||||||
llvm::SmallPtrSet<BlockVarDecl*,10> AlreadyWarned;
|
llvm::SmallPtrSet<VarDecl*,10> AlreadyWarned;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UninitializedValuesChecker(ASTContext &ctx, Diagnostic &diags)
|
UninitializedValuesChecker(ASTContext &ctx, Diagnostic &diags)
|
||||||
|
@ -248,7 +255,7 @@ public:
|
||||||
|
|
||||||
virtual void ObserveDeclRefExpr(UninitializedValues::ValTy& V,
|
virtual void ObserveDeclRefExpr(UninitializedValues::ValTy& V,
|
||||||
UninitializedValues::AnalysisDataTy& AD,
|
UninitializedValues::AnalysisDataTy& AD,
|
||||||
DeclRefExpr* DR, BlockVarDecl* VD) {
|
DeclRefExpr* DR, VarDecl* VD) {
|
||||||
|
|
||||||
assert ( AD.isTracked(VD) && "Unknown VarDecl.");
|
assert ( AD.isTracked(VD) && "Unknown VarDecl.");
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,6 @@ using namespace CodeGen;
|
||||||
void CodeGenFunction::EmitDecl(const Decl &D) {
|
void CodeGenFunction::EmitDecl(const Decl &D) {
|
||||||
switch (D.getKind()) {
|
switch (D.getKind()) {
|
||||||
default: assert(0 && "Unknown decl kind!");
|
default: assert(0 && "Unknown decl kind!");
|
||||||
case Decl::FileVar:
|
|
||||||
assert(0 && "Should not see file-scope variables inside a function!");
|
|
||||||
case Decl::ParmVar:
|
case Decl::ParmVar:
|
||||||
assert(0 && "Parmdecls should not be in declstmts!");
|
assert(0 && "Parmdecls should not be in declstmts!");
|
||||||
case Decl::Typedef: // typedef int X;
|
case Decl::Typedef: // typedef int X;
|
||||||
|
@ -36,8 +34,11 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
|
||||||
// None of these decls require codegen support.
|
// None of these decls require codegen support.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Decl::BlockVar:
|
case Decl::Var:
|
||||||
return EmitBlockVarDecl(cast<BlockVarDecl>(D));
|
if (cast<VarDecl>(D).isBlockVarDecl())
|
||||||
|
return EmitBlockVarDecl(cast<VarDecl>(D));
|
||||||
|
assert(0 && "Should not see file-scope variables inside a function!");
|
||||||
|
|
||||||
case Decl::EnumConstant:
|
case Decl::EnumConstant:
|
||||||
return EmitEnumConstantDecl(cast<EnumConstantDecl>(D));
|
return EmitEnumConstantDecl(cast<EnumConstantDecl>(D));
|
||||||
}
|
}
|
||||||
|
@ -49,7 +50,7 @@ void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
|
||||||
|
|
||||||
/// EmitBlockVarDecl - This method handles emission of any variable declaration
|
/// EmitBlockVarDecl - This method handles emission of any variable declaration
|
||||||
/// inside a function, including static vars etc.
|
/// inside a function, including static vars etc.
|
||||||
void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
|
void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
|
||||||
switch (D.getStorageClass()) {
|
switch (D.getStorageClass()) {
|
||||||
case VarDecl::Static:
|
case VarDecl::Static:
|
||||||
return EmitStaticBlockVarDecl(D);
|
return EmitStaticBlockVarDecl(D);
|
||||||
|
@ -65,7 +66,7 @@ void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) {
|
void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
|
||||||
QualType Ty = D.getType();
|
QualType Ty = D.getType();
|
||||||
assert(Ty->isConstantSizeType() && "VLAs can't be static");
|
assert(Ty->isConstantSizeType() && "VLAs can't be static");
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) {
|
||||||
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
|
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
|
||||||
/// variable declaration with auto, register, or no storage class specifier.
|
/// variable declaration with auto, register, or no storage class specifier.
|
||||||
/// These turn into simple stack objects.
|
/// These turn into simple stack objects.
|
||||||
void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
|
void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
||||||
QualType Ty = D.getType();
|
QualType Ty = D.getType();
|
||||||
|
|
||||||
llvm::Value *DeclPtr;
|
llvm::Value *DeclPtr;
|
||||||
|
|
|
@ -338,20 +338,20 @@ void CodeGenFunction::EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst,
|
||||||
|
|
||||||
|
|
||||||
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
||||||
const ValueDecl *D = E->getDecl();
|
const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
|
||||||
if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) {
|
|
||||||
const VarDecl *VD = cast<VarDecl>(D);
|
if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD))) {
|
||||||
if (VD->getStorageClass() == VarDecl::Extern)
|
if (VD->getStorageClass() == VarDecl::Extern)
|
||||||
return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
|
return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
|
||||||
else {
|
else {
|
||||||
llvm::Value *V = LocalDeclMap[D];
|
llvm::Value *V = LocalDeclMap[VD];
|
||||||
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
|
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
|
||||||
return LValue::MakeAddr(V);
|
return LValue::MakeAddr(V);
|
||||||
}
|
}
|
||||||
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
} else if (VD && VD->isFileVarDecl()) {
|
||||||
|
return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
|
||||||
|
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
|
||||||
return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false));
|
return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false));
|
||||||
} else if (const FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
|
|
||||||
return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(FVD, false));
|
|
||||||
}
|
}
|
||||||
assert(0 && "Unimp declref");
|
assert(0 && "Unimp declref");
|
||||||
//an invalid LValue, but the assert will
|
//an invalid LValue, but the assert will
|
||||||
|
|
|
@ -541,11 +541,13 @@ public:
|
||||||
ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
|
ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
|
||||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
|
||||||
return CGM.GetAddrOfFunctionDecl(FD, false);
|
return CGM.GetAddrOfFunctionDecl(FD, false);
|
||||||
if (const FileVarDecl* VD = dyn_cast<FileVarDecl>(Decl))
|
if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
|
||||||
return CGM.GetAddrOfGlobalVar(VD, false);
|
if (VD->isFileVarDecl())
|
||||||
if (const BlockVarDecl* BVD = dyn_cast<BlockVarDecl>(Decl)) {
|
return CGM.GetAddrOfGlobalVar(VD, false);
|
||||||
assert(CGF && "Can't access static local vars without CGF");
|
else if (VD->isBlockVarDecl()) {
|
||||||
return CGF->GetAddrOfStaticLocalVar(BVD);
|
assert(CGF && "Can't access static local vars without CGF");
|
||||||
|
return CGF->GetAddrOfStaticLocalVar(VD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Constant *
|
llvm::Constant *
|
||||||
CodeGenFunction::GetAddrOfStaticLocalVar(const BlockVarDecl *BVD) {
|
CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
|
||||||
return cast<llvm::Constant>(LocalDeclMap[BVD]);
|
return cast<llvm::Constant>(LocalDeclMap[BVD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace clang {
|
||||||
class ObjCIvarRefExpr;
|
class ObjCIvarRefExpr;
|
||||||
class MemberExpr;
|
class MemberExpr;
|
||||||
|
|
||||||
class BlockVarDecl;
|
class VarDecl;
|
||||||
class EnumConstantDecl;
|
class EnumConstantDecl;
|
||||||
class ParmVarDecl;
|
class ParmVarDecl;
|
||||||
class FieldDecl;
|
class FieldDecl;
|
||||||
|
@ -344,16 +344,16 @@ public:
|
||||||
const CGRecordLayout *getCGRecordLayout(CodeGenTypes &CGT, QualType RTy);
|
const CGRecordLayout *getCGRecordLayout(CodeGenTypes &CGT, QualType RTy);
|
||||||
|
|
||||||
/// GetAddrOfStaticLocalVar - Return the address of a static local variable.
|
/// GetAddrOfStaticLocalVar - Return the address of a static local variable.
|
||||||
llvm::Constant *GetAddrOfStaticLocalVar(const BlockVarDecl *BVD);
|
llvm::Constant *GetAddrOfStaticLocalVar(const VarDecl *BVD);
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Declaration Emission
|
// Declaration Emission
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
void EmitDecl(const Decl &D);
|
void EmitDecl(const Decl &D);
|
||||||
void EmitEnumConstantDecl(const EnumConstantDecl &D);
|
void EmitEnumConstantDecl(const EnumConstantDecl &D);
|
||||||
void EmitBlockVarDecl(const BlockVarDecl &D);
|
void EmitBlockVarDecl(const VarDecl &D);
|
||||||
void EmitLocalBlockVarDecl(const BlockVarDecl &D);
|
void EmitLocalBlockVarDecl(const VarDecl &D);
|
||||||
void EmitStaticBlockVarDecl(const BlockVarDecl &D);
|
void EmitStaticBlockVarDecl(const VarDecl &D);
|
||||||
void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
|
void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -288,7 +288,7 @@ llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
|
||||||
return EmitConstantExpr(Expr);
|
return EmitConstantExpr(Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::EmitGlobalVar(const FileVarDecl *D) {
|
void CodeGenModule::EmitGlobalVar(const VarDecl *D) {
|
||||||
// If this is just a forward declaration of the variable, don't emit it now,
|
// If this is just a forward declaration of the variable, don't emit it now,
|
||||||
// allow it to be emitted lazily on its first use.
|
// allow it to be emitted lazily on its first use.
|
||||||
if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
|
if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
|
||||||
|
@ -352,9 +352,10 @@ void CodeGenModule::EmitGlobalVar(const FileVarDecl *D) {
|
||||||
|
|
||||||
/// EmitGlobalVarDeclarator - Emit all the global vars attached to the specified
|
/// EmitGlobalVarDeclarator - Emit all the global vars attached to the specified
|
||||||
/// declarator chain.
|
/// declarator chain.
|
||||||
void CodeGenModule::EmitGlobalVarDeclarator(const FileVarDecl *D) {
|
void CodeGenModule::EmitGlobalVarDeclarator(const VarDecl *D) {
|
||||||
for (; D; D = cast_or_null<FileVarDecl>(D->getNextDeclarator()))
|
for (; D; D = cast_or_null<VarDecl>(D->getNextDeclarator()))
|
||||||
EmitGlobalVar(D);
|
if (D->isFileVarDecl())
|
||||||
|
EmitGlobalVar(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
|
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace clang {
|
||||||
class ValueDecl;
|
class ValueDecl;
|
||||||
class VarDecl;
|
class VarDecl;
|
||||||
class TypeDecl;
|
class TypeDecl;
|
||||||
class FileVarDecl;
|
|
||||||
struct LangOptions;
|
struct LangOptions;
|
||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
|
|
||||||
|
@ -103,8 +102,8 @@ public:
|
||||||
|
|
||||||
void EmitObjCMethod(const ObjCMethodDecl *OMD);
|
void EmitObjCMethod(const ObjCMethodDecl *OMD);
|
||||||
void EmitFunction(const FunctionDecl *FD);
|
void EmitFunction(const FunctionDecl *FD);
|
||||||
void EmitGlobalVar(const FileVarDecl *D);
|
void EmitGlobalVar(const VarDecl *D);
|
||||||
void EmitGlobalVarDeclarator(const FileVarDecl *D);
|
void EmitGlobalVarDeclarator(const VarDecl *D);
|
||||||
void UpdateCompletedType(const TagDecl *D);
|
void UpdateCompletedType(const TagDecl *D);
|
||||||
llvm::Constant *EmitGlobalInit(const Expr *E);
|
llvm::Constant *EmitGlobalInit(const Expr *E);
|
||||||
llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
|
llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
|
||||||
|
|
|
@ -63,8 +63,9 @@ namespace {
|
||||||
|
|
||||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||||
Builder->EmitFunction(FD);
|
Builder->EmitFunction(FD);
|
||||||
} else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
|
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
||||||
Builder->EmitGlobalVarDeclarator(FVD);
|
if (VD->isFileVarDecl())
|
||||||
|
Builder->EmitGlobalVarDeclarator(VD);
|
||||||
} else if (isa<ObjCClassDecl>(D) || isa<ObjCCategoryDecl>(D)) {
|
} else if (isa<ObjCClassDecl>(D) || isa<ObjCCategoryDecl>(D)) {
|
||||||
// Forward declaration. Only used for type checking.
|
// Forward declaration. Only used for type checking.
|
||||||
} else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){
|
} else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){
|
||||||
|
|
|
@ -372,26 +372,23 @@ VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
|
||||||
return New;
|
return New;
|
||||||
}
|
}
|
||||||
// We've verified the types match, now handle "tentative" definitions.
|
// We've verified the types match, now handle "tentative" definitions.
|
||||||
FileVarDecl *OldFSDecl = dyn_cast<FileVarDecl>(Old);
|
if (Old->isFileVarDecl() && New->isFileVarDecl()) {
|
||||||
FileVarDecl *NewFSDecl = dyn_cast<FileVarDecl>(New);
|
|
||||||
|
|
||||||
if (OldFSDecl && NewFSDecl) {
|
|
||||||
// Handle C "tentative" external object definitions (C99 6.9.2).
|
// Handle C "tentative" external object definitions (C99 6.9.2).
|
||||||
bool OldIsTentative = false;
|
bool OldIsTentative = false;
|
||||||
bool NewIsTentative = false;
|
bool NewIsTentative = false;
|
||||||
|
|
||||||
if (!OldFSDecl->getInit() &&
|
if (!Old->getInit() &&
|
||||||
(OldFSDecl->getStorageClass() == VarDecl::None ||
|
(Old->getStorageClass() == VarDecl::None ||
|
||||||
OldFSDecl->getStorageClass() == VarDecl::Static))
|
Old->getStorageClass() == VarDecl::Static))
|
||||||
OldIsTentative = true;
|
OldIsTentative = true;
|
||||||
|
|
||||||
// FIXME: this check doesn't work (since the initializer hasn't been
|
// FIXME: this check doesn't work (since the initializer hasn't been
|
||||||
// attached yet). This check should be moved to FinalizeDeclaratorGroup.
|
// attached yet). This check should be moved to FinalizeDeclaratorGroup.
|
||||||
// Unfortunately, by the time we get to FinializeDeclaratorGroup, we've
|
// Unfortunately, by the time we get to FinializeDeclaratorGroup, we've
|
||||||
// thrown out the old decl.
|
// thrown out the old decl.
|
||||||
if (!NewFSDecl->getInit() &&
|
if (!New->getInit() &&
|
||||||
(NewFSDecl->getStorageClass() == VarDecl::None ||
|
(New->getStorageClass() == VarDecl::None ||
|
||||||
NewFSDecl->getStorageClass() == VarDecl::Static))
|
New->getStorageClass() == VarDecl::Static))
|
||||||
; // change to NewIsTentative = true; once the code is moved.
|
; // change to NewIsTentative = true; once the code is moved.
|
||||||
|
|
||||||
if (NewIsTentative || OldIsTentative)
|
if (NewIsTentative || OldIsTentative)
|
||||||
|
@ -880,13 +877,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
||||||
R.getAsString());
|
R.getAsString());
|
||||||
InvalidDecl = true;
|
InvalidDecl = true;
|
||||||
}
|
}
|
||||||
NewVD = FileVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
|
NewVD = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
|
||||||
II, R, SC,
|
II, R, SC, LastDeclarator);
|
||||||
LastDeclarator);
|
|
||||||
} else {
|
} else {
|
||||||
NewVD = BlockVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
|
NewVD = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
|
||||||
II, R, SC,
|
II, R, SC, LastDeclarator);
|
||||||
LastDeclarator);
|
|
||||||
}
|
}
|
||||||
// Handle attributes prior to checking for duplicates in MergeVarDecl
|
// Handle attributes prior to checking for duplicates in MergeVarDecl
|
||||||
HandleDeclAttributes(NewVD, D.getDeclSpec().getAttributes(),
|
HandleDeclAttributes(NewVD, D.getDeclSpec().getAttributes(),
|
||||||
|
@ -952,23 +947,23 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
|
||||||
// Get the decls type and save a reference for later, since
|
// Get the decls type and save a reference for later, since
|
||||||
// CheckInitializerTypes may change it.
|
// CheckInitializerTypes may change it.
|
||||||
QualType DclT = VDecl->getType(), SavT = DclT;
|
QualType DclT = VDecl->getType(), SavT = DclT;
|
||||||
if (BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(VDecl)) {
|
if (VDecl->isBlockVarDecl()) {
|
||||||
VarDecl::StorageClass SC = BVD->getStorageClass();
|
VarDecl::StorageClass SC = VDecl->getStorageClass();
|
||||||
if (SC == VarDecl::Extern) { // C99 6.7.8p5
|
if (SC == VarDecl::Extern) { // C99 6.7.8p5
|
||||||
Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
|
Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
|
||||||
BVD->setInvalidDecl();
|
VDecl->setInvalidDecl();
|
||||||
} else if (!BVD->isInvalidDecl()) {
|
} else if (!VDecl->isInvalidDecl()) {
|
||||||
if (CheckInitializerTypes(Init, DclT))
|
if (CheckInitializerTypes(Init, DclT))
|
||||||
BVD->setInvalidDecl();
|
VDecl->setInvalidDecl();
|
||||||
if (SC == VarDecl::Static) // C99 6.7.8p4.
|
if (SC == VarDecl::Static) // C99 6.7.8p4.
|
||||||
CheckForConstantInitializer(Init, DclT);
|
CheckForConstantInitializer(Init, DclT);
|
||||||
}
|
}
|
||||||
} else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(VDecl)) {
|
} else if (VDecl->isFileVarDecl()) {
|
||||||
if (FVD->getStorageClass() == VarDecl::Extern)
|
if (VDecl->getStorageClass() == VarDecl::Extern)
|
||||||
Diag(VDecl->getLocation(), diag::warn_extern_init);
|
Diag(VDecl->getLocation(), diag::warn_extern_init);
|
||||||
if (!FVD->isInvalidDecl())
|
if (!VDecl->isInvalidDecl())
|
||||||
if (CheckInitializerTypes(Init, DclT))
|
if (CheckInitializerTypes(Init, DclT))
|
||||||
FVD->setInvalidDecl();
|
VDecl->setInvalidDecl();
|
||||||
|
|
||||||
// C99 6.7.8p4. All file scoped initializers need to be constant.
|
// C99 6.7.8p4. All file scoped initializers need to be constant.
|
||||||
CheckForConstantInitializer(Init, DclT);
|
CheckForConstantInitializer(Init, DclT);
|
||||||
|
@ -1012,13 +1007,12 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
|
||||||
VarDecl *IDecl = dyn_cast<VarDecl>(ID);
|
VarDecl *IDecl = dyn_cast<VarDecl>(ID);
|
||||||
if (!IDecl)
|
if (!IDecl)
|
||||||
continue;
|
continue;
|
||||||
FileVarDecl *FVD = dyn_cast<FileVarDecl>(IDecl);
|
|
||||||
BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(IDecl);
|
|
||||||
QualType T = IDecl->getType();
|
QualType T = IDecl->getType();
|
||||||
|
|
||||||
// C99 6.7.5.2p2: If an identifier is declared to be an object with
|
// C99 6.7.5.2p2: If an identifier is declared to be an object with
|
||||||
// static storage duration, it shall not have a variable length array.
|
// static storage duration, it shall not have a variable length array.
|
||||||
if ((FVD || BVD) && IDecl->getStorageClass() == VarDecl::Static) {
|
if ((IDecl->isFileVarDecl() || IDecl->isBlockVarDecl()) &&
|
||||||
|
IDecl->getStorageClass() == VarDecl::Static) {
|
||||||
if (T->getAsVariableArrayType()) {
|
if (T->getAsVariableArrayType()) {
|
||||||
Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
|
Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
|
||||||
IDecl->setInvalidDecl();
|
IDecl->setInvalidDecl();
|
||||||
|
@ -1026,7 +1020,8 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
|
||||||
}
|
}
|
||||||
// Block scope. C99 6.7p7: If an identifier for an object is declared with
|
// Block scope. C99 6.7p7: If an identifier for an object is declared with
|
||||||
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
|
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
|
||||||
if (BVD && IDecl->getStorageClass() != VarDecl::Extern) {
|
if (IDecl->isBlockVarDecl() &&
|
||||||
|
IDecl->getStorageClass() != VarDecl::Extern) {
|
||||||
if (T->isIncompleteType() && !IDecl->isInvalidDecl()) {
|
if (T->isIncompleteType() && !IDecl->isInvalidDecl()) {
|
||||||
Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type,
|
Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type,
|
||||||
T.getAsString());
|
T.getAsString());
|
||||||
|
@ -1038,8 +1033,9 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
|
||||||
// storage-class specifier or with the storage-class specifier "static",
|
// storage-class specifier or with the storage-class specifier "static",
|
||||||
// constitutes a tentative definition. Note: A tentative definition with
|
// constitutes a tentative definition. Note: A tentative definition with
|
||||||
// external linkage is valid (C99 6.2.2p5).
|
// external linkage is valid (C99 6.2.2p5).
|
||||||
if (FVD && !FVD->getInit() && (FVD->getStorageClass() == VarDecl::Static ||
|
if (IDecl && !IDecl->getInit() &&
|
||||||
FVD->getStorageClass() == VarDecl::None)) {
|
(IDecl->getStorageClass() == VarDecl::Static ||
|
||||||
|
IDecl->getStorageClass() == VarDecl::None)) {
|
||||||
if (T->isIncompleteArrayType()) {
|
if (T->isIncompleteArrayType()) {
|
||||||
// C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete
|
// C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete
|
||||||
// array to be completed. Don't issue a diagnostic.
|
// array to be completed. Don't issue a diagnostic.
|
||||||
|
|
|
@ -74,13 +74,14 @@ namespace {
|
||||||
return S->Diag(DRE->getSourceRange().getBegin(),
|
return S->Diag(DRE->getSourceRange().getBegin(),
|
||||||
diag::err_param_default_argument_references_param,
|
diag::err_param_default_argument_references_param,
|
||||||
Param->getName(), DefaultArg->getSourceRange());
|
Param->getName(), DefaultArg->getSourceRange());
|
||||||
} else if (BlockVarDecl *BlockVar = dyn_cast<BlockVarDecl>(Decl)) {
|
} else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) {
|
||||||
// C++ [dcl.fct.default]p7
|
// C++ [dcl.fct.default]p7
|
||||||
// Local variables shall not be used in default argument
|
// Local variables shall not be used in default argument
|
||||||
// expressions.
|
// expressions.
|
||||||
return S->Diag(DRE->getSourceRange().getBegin(),
|
if (VDecl->isBlockVarDecl())
|
||||||
diag::err_param_default_argument_references_local,
|
return S->Diag(DRE->getSourceRange().getBegin(),
|
||||||
BlockVar->getName(), DefaultArg->getSourceRange());
|
diag::err_param_default_argument_references_local,
|
||||||
|
VDecl->getName(), DefaultArg->getSourceRange());
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: when Clang has support for member functions, "this"
|
// FIXME: when Clang has support for member functions, "this"
|
||||||
|
|
|
@ -521,10 +521,10 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
|
||||||
// C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
|
// C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
|
||||||
// identifiers for objects having storage class 'auto' or 'register'.
|
// identifiers for objects having storage class 'auto' or 'register'.
|
||||||
for (ScopedDecl *D = DS->getDecl(); D; D = D->getNextDeclarator()) {
|
for (ScopedDecl *D = DS->getDecl(); D; D = D->getNextDeclarator()) {
|
||||||
BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(D);
|
VarDecl *VD = dyn_cast<VarDecl>(D);
|
||||||
if (BVD && !BVD->hasLocalStorage())
|
if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage())
|
||||||
BVD = 0;
|
VD = 0;
|
||||||
if (BVD == 0)
|
if (VD == 0)
|
||||||
Diag(dyn_cast<ScopedDecl>(D)->getLocation(),
|
Diag(dyn_cast<ScopedDecl>(D)->getLocation(),
|
||||||
diag::err_non_variable_decl_in_for);
|
diag::err_non_variable_decl_in_for);
|
||||||
// FIXME: mark decl erroneous!
|
// FIXME: mark decl erroneous!
|
||||||
|
@ -556,13 +556,12 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
|
||||||
// C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
|
// C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
|
||||||
// identifiers for objects having storage class 'auto' or 'register'.
|
// identifiers for objects having storage class 'auto' or 'register'.
|
||||||
ScopedDecl *D = DS->getDecl();
|
ScopedDecl *D = DS->getDecl();
|
||||||
BlockVarDecl *BVD = cast<BlockVarDecl>(D);
|
VarDecl *VD = cast<VarDecl>(D);
|
||||||
if (!BVD->hasLocalStorage())
|
if (VD->isBlockVarDecl() && !VD->hasLocalStorage())
|
||||||
return Diag(BVD->getLocation(), diag::err_non_variable_decl_in_for);
|
return Diag(VD->getLocation(), diag::err_non_variable_decl_in_for);
|
||||||
if (D->getNextDeclarator())
|
if (D->getNextDeclarator())
|
||||||
return Diag(D->getLocation(), diag::err_toomany_element_decls);
|
return Diag(D->getLocation(), diag::err_toomany_element_decls);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
FirstType = static_cast<Expr*>(first)->getType();
|
FirstType = static_cast<Expr*>(first)->getType();
|
||||||
if (!isObjCObjectPointerType(FirstType))
|
if (!isObjCObjectPointerType(FirstType))
|
||||||
Diag(ForLoc, diag::err_selector_element_type,
|
Diag(ForLoc, diag::err_selector_element_type,
|
||||||
|
|
Loading…
Reference in New Issue