[cfe-commits] r39644 - in /cfe/cfe/trunk: AST/Decl.cpp AST/Expr.cpp Parse/ParseDecl.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Parse/Action.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:46:35 PDT 2007
Author: clattner
Date: Wed Jul 11 11:46:35 2007
New Revision: 39644
URL: http://llvm.org/viewvc/llvm-project?rev=39644&view=rev
Log:
Implement capturing of enum values and chaining of enums together.
Modified:
cfe/cfe/trunk/AST/Decl.cpp
cfe/cfe/trunk/AST/Expr.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/include/clang/AST/Decl.h
cfe/cfe/trunk/include/clang/Parse/Action.h
Modified: cfe/cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Decl.cpp?rev=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Decl.cpp (original)
+++ cfe/cfe/trunk/AST/Decl.cpp Wed Jul 11 11:46:35 2007
@@ -136,21 +136,6 @@
}
-/// defineElements - When created, EnumDecl correspond to a forward declared
-/// enum. This method is used to mark the decl as being defined, with the
-/// specified contents.
-void EnumDecl::defineElements(EnumConstantDecl **Elts, unsigned NumElts) {
- assert(!isDefinition() && "Cannot redefine enums!");
- setDefinition(true);
- NumElements = NumElts;
- if (NumElts) {
- Elements = new EnumConstantDecl*[NumElts];
- memcpy(Elements, Elts, NumElts*sizeof(Decl*));
- }
-}
-
-
-
/// defineBody - When created, RecordDecl's correspond to a forward declared
/// record. This method is used to mark the decl as being defined, with the
/// specified contents.
Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:46:35 2007
@@ -206,6 +206,9 @@
/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero,
/// comma, etc
+///
+/// FIXME: This should ext-warn on overflow during evaluation! ISO C does not
+/// permit this.
bool Expr::isIntegerConstantExpr(APSInt &Result, SourceLocation *Loc,
bool isEvaluated) const {
switch (getStmtClass()) {
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:46:35 2007
@@ -770,6 +770,8 @@
SmallVector<DeclTy*, 32> EnumConstantDecls;
+ DeclTy *LastEnumConstDecl = 0;
+
// Parse the enumerator-list.
while (Tok.getKind() == tok::identifier) {
IdentifierInfo *Ident = Tok.getIdentifierInfo();
@@ -787,10 +789,12 @@
}
// Install the enumerator constant into EnumDecl.
- DeclTy *ConstDecl = Actions.ParseEnumConstant(CurScope, EnumDecl,
- IdentLoc, Ident,
- EqualLoc, AssignedVal);
- EnumConstantDecls.push_back(ConstDecl);
+ DeclTy *EnumConstDecl = Actions.ParseEnumConstant(CurScope, EnumDecl,
+ LastEnumConstDecl,
+ IdentLoc, Ident,
+ EqualLoc, AssignedVal);
+ EnumConstantDecls.push_back(EnumConstDecl);
+ LastEnumConstDecl = EnumConstDecl;
if (Tok.getKind() != tok::comma)
break;
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:46:35 2007
@@ -116,6 +116,7 @@
virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
DeclTy **Fields, unsigned NumFields);
virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
+ DeclTy *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
SourceLocation EqualLoc, ExprTy *Val);
virtual void ParseEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:46:35 2007
@@ -849,10 +849,14 @@
Record->defineBody(&RecFields[0], RecFields.size());
}
-Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *EnumDeclX,
+Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *theEnumDecl,
+ DeclTy *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id,
- SourceLocation EqualLoc, ExprTy *Val) {
- EnumDecl *TheEnumDecl = cast<EnumDecl>(static_cast<Decl*>(EnumDeclX));
+ SourceLocation EqualLoc, ExprTy *val) {
+ theEnumDecl = theEnumDecl; // silence unused warning.
+ EnumConstantDecl *LastEnumConst =
+ cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
+ Expr *Val = static_cast<Expr*>(val);
// Verify that there isn't already something declared with this name in this
// scope.
@@ -863,19 +867,43 @@
else
Diag(IdLoc, diag::err_redefinition, Id->getName());
Diag(PrevDecl->getLocation(), diag::err_previous_definition);
+ // FIXME: Don't leak memory: delete Val;
return 0;
}
}
- SourceLocation expLoc;
- // C99 6.7.2.2p2: Make sure we have an integer constant expression.
- // FIXME: Capture this value in the enumconstantdecl.
- if (Val && !((Expr *)Val)->isIntegerConstantExpr(&expLoc)) {
- Diag(expLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
- return 0;
+
+ APSInt EnumVal(32);
+ QualType EltTy;
+ if (Val) {
+ // C99 6.7.2.2p2: Make sure we have an integer constant expression.
+ SourceLocation ExpLoc;
+ if (!Val->isIntegerConstantExpr(EnumVal, &ExpLoc)) {
+ Diag(ExpLoc, diag::err_enum_value_not_integer_constant_expr,
+ Id->getName());
+ // FIXME: Don't leak memory: delete Val;
+ return 0;
+ }
+ EltTy = Val->getType();
+ } else if (LastEnumConst) {
+ // Assign the last value + 1.
+ EnumVal = LastEnumConst->getInitVal();
+ ++EnumVal;
+ // FIXME: detect overflow!
+ EltTy = LastEnumConst->getType();
+ } else {
+ // First value, set to zero.
+ EltTy = Context.IntTy;
+ // FIXME: Resize EnumVal to the size of int.
}
- QualType Ty = Context.getTagDeclType(TheEnumDecl);
- // FIXME: Chain EnumConstantDecl's together.
- EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val, 0);
+
+ // TODO: Default promotions to int/uint.
+
+ // TODO: If the result value doesn't fit in an int, it must be a long or long
+ // long value. ISO C does not support this, but GCC does as an extension,
+ // emit a warning.
+
+ EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, EltTy, Val, EnumVal,
+ LastEnumConst);
// Register this decl in the current scope stack.
New->setNext(Id->getFETokenInfo<Decl>());
@@ -889,17 +917,18 @@
EnumDecl *Enum = cast<EnumDecl>(static_cast<Decl*>(EnumDeclX));
assert(!Enum->isDefinition() && "Enum redefinitions can't reach here");
- // Verify that all the values are okay.
- SmallVector<EnumConstantDecl*, 32> Values;
+ // Verify that all the values are okay, and reverse the list.
+ EnumConstantDecl *EltList = 0;
for (unsigned i = 0; i != NumElements; ++i) {
EnumConstantDecl *ECD =
cast_or_null<EnumConstantDecl>(static_cast<Decl*>(Elements[i]));
if (!ECD) continue; // Already issued a diagnostic.
-
- Values.push_back(ECD);
+
+ ECD->setNextDeclarator(EltList);
+ EltList = ECD;
}
- Enum->defineElements(&Values[0], Values.size());
+ Enum->defineElements(EltList);
}
void Sema::AddTopLevelDecl(Decl *current, Decl *last) {
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=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:46:35 2007
@@ -16,6 +16,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/AST/Type.h"
+#include "llvm/ADT/APSInt.h"
namespace llvm {
namespace clang {
@@ -274,11 +275,16 @@
/// TagType for the X EnumDecl.
class EnumConstantDecl : public ValueDecl {
Expr *Init; // an integer constant expression
+ APSInt Val; // The value.
public:
EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
- Decl *PrevDecl)
- : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E) {}
+ const APSInt &V, Decl *PrevDecl)
+ : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
+ const Expr *getInitExpr() const { return Init; }
+ Expr *getInitExpr() { return Init; }
+ const APSInt &getInitVal() const { return Val; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == EnumConstant;
@@ -363,21 +369,23 @@
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
/// enums.
class EnumDecl : public TagDecl {
- /// Elements/NumElements - This is a new[]'d array of pointers to
- /// EnumConstantDecls.
- EnumConstantDecl **Elements; // Null if not defined.
- int NumElements; // -1 if not defined.
+ /// ElementList - this is a linked list of EnumConstantDecl's which are linked
+ /// together through their getNextDeclarator pointers.
+ EnumConstantDecl *ElementList;
public:
EnumDecl(SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
: TagDecl(Enum, L, Id, PrevDecl) {
- Elements = 0;
- NumElements = -1;
+ ElementList = 0;
}
/// defineElements - When created, EnumDecl correspond to a forward declared
/// enum. This method is used to mark the decl as being defined, with the
- /// specified contents.
- void defineElements(EnumConstantDecl **Elements, unsigned NumElements);
+ /// specified list of enums.
+ void defineElements(EnumConstantDecl *ListHead) {
+ assert(!isDefinition() && "Cannot redefine enums!");
+ ElementList = ListHead;
+ setDefinition(true);
+ }
static bool classof(const Decl *D) {
return D->getKind() == Enum;
Modified: cfe/cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Action.h?rev=39644&r1=39643&r2=39644&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:46:35 2007
@@ -169,6 +169,7 @@
DeclTy **Fields, unsigned NumFields) {}
virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
+ DeclTy *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
SourceLocation EqualLoc, ExprTy *Val) {
return 0;
More information about the cfe-commits
mailing list