[cfe-commits] r39379 - in /cfe/cfe/trunk: AST/SemaDecl.cpp AST/SemaExpr.cpp Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/AST/Decl.h include/clang/AST/Expr.h include/clang/Basic/DiagnosticKinds.def
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:43:47 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:43:47 2007
New Revision: 39379
URL: http://llvm.org/viewvc/llvm-project?rev=39379&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Typechecking for ++/-- not operating on canonical type (fixed).
- Many changes to Decl.h...
-- Changed ObjectDecl->ValueDecl.
-- ValueDecl doesn't define a storage class. The storage class is now
defined by VarDecl/FunctionDecl. EnumConstant decls don't need a storage class.
-- FieldDecl now inherits directly from Decl (it is not a value).
- Changed SemaExpr to use the new Decl.h. Also added a couple diagnostics for
bogus storage class usage. For example:
z.c:6:10: error: illegal storage class on function
auto int func();
^
z.c:7:14: error: illegal storage class on file-scoped variable
register int b;
^
Modified:
cfe/cfe/trunk/AST/SemaDecl.cpp
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/Decl.h
cfe/cfe/trunk/include/clang/AST/Expr.h
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:43:47 2007
@@ -207,7 +207,7 @@
return New;
}
// We've verified the types match, now check if Old is "extern".
- if (Old->getStorageClass() != ObjectDecl::Extern) {
+ if (Old->getStorageClass() != VarDecl::Extern) {
Diag(New->getLocation(), diag::err_redefinition, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
}
@@ -224,7 +224,6 @@
return 0;
}
-
Action::DeclTy *
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
DeclTy *LastInGroup) {
@@ -249,9 +248,21 @@
New = NewTD;
} else if (D.isFunctionDeclarator()) {
TypeRef R = GetTypeForDeclarator(D, S);
- if (R.isNull()) return 0;
+ if (R.isNull()) return 0; // FIXME: "auto func();" passes through...
- FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R);
+ FunctionDecl::StorageClass SC;
+ switch (D.getDeclSpec().getStorageClassSpec()) {
+ default: assert(0 && "Unknown storage class!");
+ case DeclSpec::SCS_auto:
+ case DeclSpec::SCS_register:
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_func, R);
+ return 0;
+ case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
+ case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break;
+ case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
+ }
+
+ FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC);
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
@@ -263,25 +274,23 @@
TypeRef R = GetTypeForDeclarator(D, S);
if (R.isNull()) return 0;
- ObjectDecl::StorageClass SC;
+ VarDecl *NewVD;
+ VarDecl::StorageClass SC;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
- case DeclSpec::SCS_unspecified: SC = ObjectDecl::None; break;
- case DeclSpec::SCS_extern: SC = ObjectDecl::Extern; break;
- case DeclSpec::SCS_static: SC = ObjectDecl::Static; break;
- // The following 2 should never be seen in this context.
- case DeclSpec::SCS_auto: SC = ObjectDecl::Auto; break;
- case DeclSpec::SCS_register: SC = ObjectDecl::Register; break;
- }
- VarDecl *NewVD;
-
+ case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
+ case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
+ case DeclSpec::SCS_static: SC = VarDecl::Static; break;
+ case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
+ case DeclSpec::SCS_register: SC = VarDecl::Register; break;
+ }
if (S->getParent() == 0) {
// File scope. C99 6.9.2p2: A declaration of an identifier for and
// object that has file scope without an initializer, and without a
// storage-class specifier or with the storage-class specifier "static",
// constitutes a tentative definition. Note: A tentative definition with
// external linkage is valid (C99 6.2.2p5).
- if (!Init && SC == ObjectDecl::Static) {
+ if (!Init && SC == VarDecl::Static) {
// C99 6.9.2p3: If the declaration of an identifier for an object is
// a tentative definition and has internal linkage (C99 6.2.2p3), the
// declared type shall not be an incomplete type.
@@ -290,11 +299,16 @@
return 0;
}
}
+ // FIXME: Find C99 spec reference
+ if (SC == VarDecl::Auto || SC == VarDecl::Register) {
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope, R);
+ return 0;
+ }
NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC);
} else {
// 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...
- if (SC != ObjectDecl::Extern) {
+ if (SC != VarDecl::Extern) {
if (R->isIncompleteType()) {
Diag(D.getIdentifierLoc(), diag::err_typecheck_decl_incomplete_type, R);
return 0;
@@ -341,7 +355,7 @@
// FIXME: Handle storage class (auto, register). No declarator?
VarDecl *New = new ParmVarDecl(PI.IdentLoc, II,
TypeRef::getFromOpaquePtr(PI.TypeInfo),
- ObjectDecl::None);
+ VarDecl::None);
// If this has an identifier, add it to the scope stack.
if (II) {
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:47 2007
@@ -75,9 +75,9 @@
}
}
- if (ObjectDecl *OD = dyn_cast<ObjectDecl>(D)) {
- return new DeclRefExpr(OD);
- } else if (isa<TypedefDecl>(D))
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ return new DeclRefExpr(VD, VD->getType());
+ if (isa<TypedefDecl>(D))
return Diag(Loc, diag::err_unexpected_typedef, II.getName());
assert(0 && "Invalid decl");
@@ -425,23 +425,26 @@
Action::ExprResult
Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
unsigned OpCode) {
- TypeRef type = op->getTypeRef();
+ TypeRef qType = op->getTypeRef();
- assert(!type.isNull() && "no type for increment/decrement expression");
+ assert(!qType.isNull() && "no type for increment/decrement expression");
+
+ Type *canonType = qType->getCanonicalType();
- if (const PointerType *pt = dyn_cast<PointerType>(type)) {
- if (!pt->getPointeeType()->isObjectType()) // C99 6.5.6p2
- return Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type, type);
- } else if (!type->isRealType()) // C99 6.5.2.4: isRealType excludes complex.
+ // C99 6.5.2.4p1
+ if (const PointerType *pt = dyn_cast<PointerType>(canonType)) {
+ if (!pt->getPointeeType()->isObjectType()) // C99 6.5.2.4p2, 6.5.6p2
+ return Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type, qType);
+ } else if (!canonType->isRealType()) {
// FIXME: Allow Complex as a GCC extension.
- return Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement, type);
-
+ return Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement, qType);
+ }
// At this point, we know we have a real or pointer type. As a result, the
// following predicate is overkill (i.e. it will check for types we know we
// don't have in this context). Nevertheless, we model the C99 spec closely.
- if (!type.isModifiableLvalue())
- return Diag(OpLoc, diag::err_typecheck_not_modifiable, type);
+ if (!qType.isModifiableLvalue())
+ return Diag(OpLoc, diag::err_typecheck_not_modifiable, qType);
- return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, type);
+ return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, qType);
}
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:43:47 2007
@@ -207,7 +207,7 @@
return New;
}
// We've verified the types match, now check if Old is "extern".
- if (Old->getStorageClass() != ObjectDecl::Extern) {
+ if (Old->getStorageClass() != VarDecl::Extern) {
Diag(New->getLocation(), diag::err_redefinition, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
}
@@ -224,7 +224,6 @@
return 0;
}
-
Action::DeclTy *
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
DeclTy *LastInGroup) {
@@ -249,9 +248,21 @@
New = NewTD;
} else if (D.isFunctionDeclarator()) {
TypeRef R = GetTypeForDeclarator(D, S);
- if (R.isNull()) return 0;
+ if (R.isNull()) return 0; // FIXME: "auto func();" passes through...
- FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R);
+ FunctionDecl::StorageClass SC;
+ switch (D.getDeclSpec().getStorageClassSpec()) {
+ default: assert(0 && "Unknown storage class!");
+ case DeclSpec::SCS_auto:
+ case DeclSpec::SCS_register:
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_func, R);
+ return 0;
+ case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
+ case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break;
+ case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
+ }
+
+ FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC);
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
@@ -263,25 +274,23 @@
TypeRef R = GetTypeForDeclarator(D, S);
if (R.isNull()) return 0;
- ObjectDecl::StorageClass SC;
+ VarDecl *NewVD;
+ VarDecl::StorageClass SC;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
- case DeclSpec::SCS_unspecified: SC = ObjectDecl::None; break;
- case DeclSpec::SCS_extern: SC = ObjectDecl::Extern; break;
- case DeclSpec::SCS_static: SC = ObjectDecl::Static; break;
- // The following 2 should never be seen in this context.
- case DeclSpec::SCS_auto: SC = ObjectDecl::Auto; break;
- case DeclSpec::SCS_register: SC = ObjectDecl::Register; break;
- }
- VarDecl *NewVD;
-
+ case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
+ case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
+ case DeclSpec::SCS_static: SC = VarDecl::Static; break;
+ case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
+ case DeclSpec::SCS_register: SC = VarDecl::Register; break;
+ }
if (S->getParent() == 0) {
// File scope. C99 6.9.2p2: A declaration of an identifier for and
// object that has file scope without an initializer, and without a
// storage-class specifier or with the storage-class specifier "static",
// constitutes a tentative definition. Note: A tentative definition with
// external linkage is valid (C99 6.2.2p5).
- if (!Init && SC == ObjectDecl::Static) {
+ if (!Init && SC == VarDecl::Static) {
// C99 6.9.2p3: If the declaration of an identifier for an object is
// a tentative definition and has internal linkage (C99 6.2.2p3), the
// declared type shall not be an incomplete type.
@@ -290,11 +299,16 @@
return 0;
}
}
+ // FIXME: Find C99 spec reference
+ if (SC == VarDecl::Auto || SC == VarDecl::Register) {
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope, R);
+ return 0;
+ }
NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC);
} else {
// 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...
- if (SC != ObjectDecl::Extern) {
+ if (SC != VarDecl::Extern) {
if (R->isIncompleteType()) {
Diag(D.getIdentifierLoc(), diag::err_typecheck_decl_incomplete_type, R);
return 0;
@@ -341,7 +355,7 @@
// FIXME: Handle storage class (auto, register). No declarator?
VarDecl *New = new ParmVarDecl(PI.IdentLoc, II,
TypeRef::getFromOpaquePtr(PI.TypeInfo),
- ObjectDecl::None);
+ VarDecl::None);
// If this has an identifier, add it to the scope stack.
if (II) {
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:47 2007
@@ -75,9 +75,9 @@
}
}
- if (ObjectDecl *OD = dyn_cast<ObjectDecl>(D)) {
- return new DeclRefExpr(OD);
- } else if (isa<TypedefDecl>(D))
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ return new DeclRefExpr(VD, VD->getType());
+ if (isa<TypedefDecl>(D))
return Diag(Loc, diag::err_unexpected_typedef, II.getName());
assert(0 && "Invalid decl");
@@ -425,23 +425,26 @@
Action::ExprResult
Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
unsigned OpCode) {
- TypeRef type = op->getTypeRef();
+ TypeRef qType = op->getTypeRef();
- assert(!type.isNull() && "no type for increment/decrement expression");
+ assert(!qType.isNull() && "no type for increment/decrement expression");
+
+ Type *canonType = qType->getCanonicalType();
- if (const PointerType *pt = dyn_cast<PointerType>(type)) {
- if (!pt->getPointeeType()->isObjectType()) // C99 6.5.6p2
- return Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type, type);
- } else if (!type->isRealType()) // C99 6.5.2.4: isRealType excludes complex.
+ // C99 6.5.2.4p1
+ if (const PointerType *pt = dyn_cast<PointerType>(canonType)) {
+ if (!pt->getPointeeType()->isObjectType()) // C99 6.5.2.4p2, 6.5.6p2
+ return Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type, qType);
+ } else if (!canonType->isRealType()) {
// FIXME: Allow Complex as a GCC extension.
- return Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement, type);
-
+ return Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement, qType);
+ }
// At this point, we know we have a real or pointer type. As a result, the
// following predicate is overkill (i.e. it will check for types we know we
// don't have in this context). Nevertheless, we model the C99 spec closely.
- if (!type.isModifiableLvalue())
- return Diag(OpLoc, diag::err_typecheck_not_modifiable, type);
+ if (!qType.isModifiableLvalue())
+ return Diag(OpLoc, diag::err_typecheck_not_modifiable, qType);
- return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, type);
+ return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, qType);
}
Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:43:47 2007
@@ -30,16 +30,12 @@
class Decl {
public:
enum Kind {
- FIRST_ObjectDecl,
- Function,
- BlockVariable, FileVariable, ParmVariable, // subclasses of VarDecl
- Field,
- EnumConstant,
- LAST_ObjectDecl,
- FIRST_TypeDecl,
- Typedef,
- Struct, Union, Class, Enum, // subclasses of TagDecl
- LAST_TypeDecl
+ // Concrete sub-classes of ValueDecl
+ Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
+ // Concrete sub-classes of TypeDecl
+ Typedef, Struct, Union, Class, Enum,
+ // Concrete sub-class of Decl
+ Field
};
/// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
@@ -104,56 +100,58 @@
static bool classof(const Decl *) { return true; }
};
-/// ObjectDecl - Represents a declaration of a value.
-class ObjectDecl : public Decl {
-public:
- enum StorageClass {
- None, Extern, Static, Auto, Register
- };
-private:
+/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// an lvalue) a function (in which case it is a function designator) or
+/// an enum constant.
+class ValueDecl : public Decl {
TypeRef DeclType;
- StorageClass SClass;
protected:
- ObjectDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T,
- StorageClass S = None): Decl(DK, L, Id), DeclType(T), SClass(S) {}
+ ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T):
+ Decl(DK, L, Id), DeclType(T) {}
public:
// FIXME: should rename to getTypeRef/getCanonicalTypeRef to distinguish
// TypeRef's from Type's...
TypeRef getType() const { return DeclType; }
TypeRef getCanonicalType() const { return DeclType.getCanonicalType(); }
- StorageClass getStorageClass() const { return SClass; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
- return D->getKind() > FIRST_ObjectDecl && D->getKind() < LAST_ObjectDecl;
+ return D->getKind() >= Function && D->getKind() <= EnumConstant;
}
- static bool classof(const ObjectDecl *D) { return true; }
+ static bool classof(const ValueDecl *D) { return true; }
};
/// VarDecl - An instance of this class is created to represent a variable
/// declaration or definition.
-class VarDecl : public ObjectDecl {
- // TODO: Initializer.
-protected:
- VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T, StorageClass S)
- : ObjectDecl(DK, L, Id, T, S) {}
-public:
+class VarDecl : public ValueDecl {
+public:
+ enum StorageClass {
+ None, Extern, Static, Auto, Register
+ };
+ StorageClass getStorageClass() const { return SClass; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= BlockVariable && D->getKind() <= ParmVariable;
}
static bool classof(const VarDecl *D) { return true; }
+protected:
+ VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T,
+ StorageClass SC)
+ : ValueDecl(DK, L, Id, T) {}
+private:
+ StorageClass SClass;
+ // TODO: Initializer.
};
/// BlockVarDecl - Represent a local variable declaration.
class BlockVarDecl : public VarDecl {
public:
- BlockVarDecl(SourceLocation L, IdentifierInfo *Id,
- TypeRef T, StorageClass S)
+ BlockVarDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T, StorageClass S)
: VarDecl(BlockVariable, L, Id, T, S) {}
// Implement isa/cast/dyncast/etc.
- static bool classof(const VarDecl *D) { return D->getKind() == BlockVariable; }
+ static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
static bool classof(const BlockVarDecl *D) { return true; }
};
@@ -163,8 +161,7 @@
/// pointer to the decl's scope, which is transient).
class FileVarDecl : public VarDecl {
public:
- FileVarDecl(SourceLocation L, IdentifierInfo *Id,
- TypeRef T, StorageClass S)
+ FileVarDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T, StorageClass S)
: VarDecl(FileVariable, L, Id, T, S) {}
// Implement isa/cast/dyncast/etc.
@@ -175,34 +172,26 @@
/// ParmVarDecl - Represent a parameter to a function.
class ParmVarDecl : public VarDecl {
public:
- ParmVarDecl(SourceLocation L, IdentifierInfo *Id,
- TypeRef T, StorageClass S)
+ ParmVarDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T, StorageClass S)
: VarDecl(ParmVariable, L, Id, T, S) {}
// Implement isa/cast/dyncast/etc.
- static bool classof(const VarDecl *D) { return D->getKind() == ParmVariable; }
+ static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
static bool classof(const ParmVarDecl *D) { return true; }
};
/// FunctionDecl - An instance of this class is created to represent a function
/// declaration or definition.
-class FunctionDecl : public ObjectDecl {
- /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
- /// parameters of this function. This is null if a prototype or if there are
- /// no formals. TODO: we could allocate this space immediately after the
- /// FunctionDecl object to save an allocation like FunctionType does.
- VarDecl **ParamInfo;
-
- Stmt *Body; // Null if a prototype.
-
- /// DeclChain - Linked list of declarations that are defined inside this
- /// function.
- Decl *DeclChain;
+class FunctionDecl : public ValueDecl {
public:
- FunctionDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T)
- : ObjectDecl(Function, L, Id, T), ParamInfo(0), Body(0), DeclChain(0) {}
+ enum StorageClass {
+ None, Extern, Static
+ };
+ FunctionDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T, StorageClass S=None)
+ : ValueDecl(Function, L, Id, T),
+ ParamInfo(0), Body(0), DeclChain(0), SClass(S) {}
virtual ~FunctionDecl();
-
+
Stmt *getBody() const { return Body; }
void setBody(Stmt *B) { Body = B; }
@@ -215,19 +204,39 @@
return ParamInfo[i];
}
void setParams(VarDecl **NewParamInfo, unsigned NumParams);
+
+ StorageClass getStorageClass() const { return SClass; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Function; }
static bool classof(const FunctionDecl *D) { return true; }
+private:
+ /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+ /// parameters of this function. This is null if a prototype or if there are
+ /// no formals. TODO: we could allocate this space immediately after the
+ /// FunctionDecl object to save an allocation like FunctionType does.
+ VarDecl **ParamInfo;
+
+ Stmt *Body; // Null if a prototype.
+
+ /// DeclChain - Linked list of declarations that are defined inside this
+ /// function.
+ Decl *DeclChain;
+
+ StorageClass SClass;
};
/// FieldDecl - An instance of this class is created by Sema::ParseField to
/// represent a member of a struct/union/class.
-class FieldDecl : public ObjectDecl {
+class FieldDecl : public Decl {
+ TypeRef DeclType;
public:
FieldDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T)
- : ObjectDecl(Field, L, Id, T) {}
+ : Decl(Field, L, Id), DeclType(T) {}
+
+ TypeRef getType() const { return DeclType; }
+ TypeRef getCanonicalType() const { return DeclType.getCanonicalType(); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
@@ -240,18 +249,17 @@
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
/// TagType for the X EnumDecl.
-class EnumConstantDecl : public ObjectDecl {
+class EnumConstantDecl : public ValueDecl {
public:
// FIXME: Capture value info.
EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T)
- : ObjectDecl(EnumConstant, L, Id, T) {}
-
+ : ValueDecl(EnumConstant, L, Id, T) {}
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == EnumConstant;
}
static bool classof(const EnumConstantDecl *D) { return true; }
-
};
@@ -270,7 +278,7 @@
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
- return D->getKind() > FIRST_TypeDecl && D->getKind() < LAST_TypeDecl;
+ return D->getKind() >= Typedef && D->getKind() <= Enum;
}
static bool classof(const TypeDecl *D) { return true; }
};
@@ -323,7 +331,7 @@
return D->getKind() == Struct || D->getKind() == Union ||
D->getKind() == Class || D->getKind() == Enum;
}
- static bool classof(const ObjectDecl *D) { return true; }
+ static bool classof(const TagDecl *D) { return true; }
protected:
void setDefinition(bool V) { IsDefinition = V; }
};
Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:43:47 2007
@@ -33,7 +33,7 @@
Expr(StmtClass SC, TypeRef T=0) : Stmt(SC), TR(T) {}
~Expr() {}
public:
- // FIXME: the return type of getType is inconsistent with ObjectDecl.
+ // FIXME: the return type of getType is inconsistent with Decls.
// this is confusing and needs to be reconciled (by making one conform).
Type *getType() const { return TR.getTypePtr(); }
TypeRef getTypeRef() const { return TR; }
@@ -53,11 +53,11 @@
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
/// enum, etc.
class DeclRefExpr : public Expr {
- ObjectDecl *D;
+ Decl *D; // a ValueDecl or EnumConstantDecl
public:
- DeclRefExpr(ObjectDecl *d) : Expr(DeclRefExprClass, d->getType()), D(d) {}
+ DeclRefExpr(Decl *d, TypeRef t) : Expr(DeclRefExprClass, t), D(d) {}
- ObjectDecl *getDecl() const { return D; }
+ Decl *getDecl() const { return D; }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39379&r1=39378&r2=39379&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:47 2007
@@ -506,6 +506,10 @@
"arithmetic on pointer to incomplete type '%s'")
DIAG(err_typecheck_decl_incomplete_type, ERROR,
"variable has incomplete type '%s'")
+DIAG(err_typecheck_sclass_fscope, ERROR,
+ "illegal storage class on file-scoped variable")
+DIAG(err_typecheck_sclass_func, ERROR,
+ "illegal storage class on function")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
More information about the cfe-commits
mailing list