[cfe-commits] r39623 - in /cfe/cfe/trunk: AST/StmtPrinter.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:21 PDT 2007
Author: clattner
Date: Wed Jul 11 11:46:21 2007
New Revision: 39623
URL: http://llvm.org/viewvc/llvm-project?rev=39623&view=rev
Log:
Finally break down and chain together decls that are defined with common declspecs,
like: int X, Y, Z;
This is required for the code gen to get to all of the declarations in a
DeclStmt, and should simplify some other code.
Modified:
cfe/cfe/trunk/AST/StmtPrinter.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/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/StmtPrinter.cpp?rev=39623&r1=39622&r2=39623&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/cfe/trunk/AST/StmtPrinter.cpp Wed Jul 11 11:46:21 2007
@@ -124,9 +124,11 @@
}
void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
- Indent();
- PrintRawDecl(Node->getDecl());
- OS << ";\n";
+ for (Decl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
+ Indent();
+ PrintRawDecl(D);
+ OS << ";\n";
+ }
}
void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39623&r1=39622&r2=39623&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:46:21 2007
@@ -279,15 +279,15 @@
if (Tok.getKind() == tok::semi) {
ConsumeToken();
- return LastDeclInGroup;
- } else {
- Diag(Tok, diag::err_parse_error);
- // Skip to end of block or statement
- SkipUntil(tok::r_brace, true);
- if (Tok.getKind() == tok::semi)
- ConsumeToken();
- return 0;
+ return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
}
+
+ Diag(Tok, diag::err_parse_error);
+ // Skip to end of block or statement
+ SkipUntil(tok::r_brace, true);
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+ return 0;
}
/// ParseSpecifierQualifierList
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39623&r1=39622&r2=39623&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:46:21 2007
@@ -98,6 +98,8 @@
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
DeclTy *LastInGroup);
+ virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
+
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
virtual void PopScope(SourceLocation Loc, Scope *S);
@@ -120,7 +122,7 @@
DeclTy **Elements, unsigned NumElements);
private:
/// Subroutines of ParseDeclarator()...
- TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D);
+ TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, Decl *LastDeclarator);
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39623&r1=39622&r2=39623&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:46:21 2007
@@ -155,7 +155,8 @@
Builtin::ID BID = (Builtin::ID)bid;
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
- FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R);
+ FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R,
+ FunctionDecl::Extern, 0);
// Find translation-unit scope to insert this function into.
while (S->getParent())
@@ -270,20 +271,21 @@
return 0;
}
-Action::DeclTy *
+Sema::DeclTy *
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
- DeclTy *LastInGroup) {
+ DeclTy *lastDeclarator) {
+ Decl *LastDeclarator = (Decl*)lastDeclarator;
IdentifierInfo *II = D.getIdentifier();
// See if this is a redefinition of a variable in the same scope.
Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
D.getIdentifierLoc(), S);
- if (!S->isDeclScope(PrevDecl))
+ if (PrevDecl && !S->isDeclScope(PrevDecl))
PrevDecl = 0; // If in outer scope, it isn't the same thing.
Decl *New;
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
- TypedefDecl *NewTD = ParseTypedefDecl(S, D);
+ TypedefDecl *NewTD = ParseTypedefDecl(S, D, LastDeclarator);
if (!NewTD) return 0;
// Merge the decl with the existing one if appropriate.
@@ -317,7 +319,8 @@
case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
}
- FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC);
+ FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC,
+ LastDeclarator);
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
@@ -368,7 +371,7 @@
if (VerifyConstantArrayType(ary, D.getIdentifierLoc()))
return 0;
}
- NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC);
+ NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
} 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...
@@ -387,7 +390,7 @@
return 0;
}
}
- NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC);
+ NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
}
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
@@ -406,11 +409,27 @@
}
if (S->getParent() == 0)
- AddTopLevelDecl(New, (Decl *)LastInGroup);
+ AddTopLevelDecl(New, LastDeclarator);
return New;
}
+/// The declarators are chained together backwards, reverse the list.
+Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
+ // Often we have single declarators, handle them quickly.
+ Decl *Group = static_cast<Decl*>(group);
+ if (Group->getNextDeclarator() == 0) return Group;
+
+ Decl *NewGroup = 0;
+ while (Group) {
+ Decl *Next = Group->getNextDeclarator();
+ Group->setNextDeclarator(NewGroup);
+ NewGroup = Group;
+ Group = Next;
+ }
+ return NewGroup;
+}
+
VarDecl *
Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
Scope *FnScope) {
@@ -426,9 +445,10 @@
}
// FIXME: Handle storage class (auto, register). No declarator?
+ // TODO: Chain to previous parameter with the prevdeclarator chain?
VarDecl *New = new ParmVarDecl(PI.IdentLoc, II,
QualType::getFromOpaquePtr(PI.TypeInfo),
- VarDecl::None);
+ VarDecl::None, 0);
// If this has an identifier, add it to the scope stack.
if (II) {
@@ -556,14 +576,16 @@
}
-TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
- assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
+TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D,
+ Decl *LastDeclarator) {
+ assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
QualType T = GetTypeForDeclarator(D, S);
if (T.isNull()) return 0;
// Scope manipulation handled by caller.
- return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T);
+ return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T,
+ LastDeclarator);
}
@@ -638,14 +660,18 @@
switch (Kind) {
default: assert(0 && "Unknown tag kind!");
case Decl::Enum:
- New = new EnumDecl(Loc, Name);
+ // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
+ // enum X { A, B, C } D; D should chain to X.
+ New = new EnumDecl(Loc, Name, 0);
// If this is an undefined enum, warn.
if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
break;
case Decl::Union:
case Decl::Struct:
case Decl::Class:
- New = new RecordDecl(Kind, Loc, Name);
+ // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
+ // struct X { int A; } D; D should chain to X.
+ New = new RecordDecl(Kind, Loc, Name, 0);
break;
}
@@ -697,7 +723,9 @@
if (VerifyConstantArrayType(ary, Loc))
return 0;
}
- return new FieldDecl(Loc, II, T);
+
+ // FIXME: Chain fielddecls together.
+ return new FieldDecl(Loc, II, T, 0);
}
void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
@@ -837,7 +865,8 @@
return 0;
}
QualType Ty = Context.getTagDeclType(TheEnumDecl);
- EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val);
+ // FIXME: Chain EnumConstantDecl's together.
+ EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val, 0);
// Register this decl in the current scope stack.
New->setNext(Id->getFETokenInfo<Decl>());
@@ -869,9 +898,8 @@
// If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
// remember this in the LastInGroupList list.
- if (last) {
+ if (last)
LastInGroupList.push_back((Decl*)last);
- }
}
/// ParseAttribute GCC __attribute__
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=39623&r1=39622&r2=39623&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:46:21 2007
@@ -64,9 +64,13 @@
///
Decl *Next;
+ /// NextDeclarator - If this decl was part of a multi-declarator declaration,
+ /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
+ Decl *NextDeclarator;
+
protected:
- Decl(Kind DK, SourceLocation L, IdentifierInfo *Id)
- : DeclKind(DK), Loc(L), Identifier(Id), Next(0) {
+ Decl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *NextDecl)
+ : DeclKind(DK), Loc(L), Identifier(Id), Next(0), NextDeclarator(NextDecl) {
if (Decl::CollectingStats()) addDeclKind(DK);
}
virtual ~Decl();
@@ -81,6 +85,13 @@
Decl *getNext() const { return Next; }
void setNext(Decl *N) { Next = N; }
+ /// getNextDeclarator - If this decl was part of a multi-declarator
+ /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
+ /// declarator. Otherwise it returns null.
+ Decl *getNextDeclarator() { return NextDeclarator; }
+ const Decl *getNextDeclarator() const { return NextDeclarator; }
+ void setNextDeclarator(Decl *N) { NextDeclarator = N; }
+
IdentifierNamespace getIdentifierNamespace() const {
switch (DeclKind) {
default: assert(0 && "Unknown decl kind!");
@@ -113,8 +124,8 @@
class ValueDecl : public Decl {
QualType DeclType;
protected:
- ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T):
- Decl(DK, L, Id), DeclType(T) {}
+ ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
+ Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
public:
QualType getType() const { return DeclType; }
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
@@ -142,8 +153,8 @@
static bool classof(const VarDecl *D) { return true; }
protected:
VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
- StorageClass SC)
- : ValueDecl(DK, L, Id, T) { SClass = SC; }
+ StorageClass SC, Decl *PrevDecl)
+ : ValueDecl(DK, L, Id, T, PrevDecl) { SClass = SC; }
private:
StorageClass SClass;
// TODO: Initializer.
@@ -152,8 +163,9 @@
/// BlockVarDecl - Represent a local variable declaration.
class BlockVarDecl : public VarDecl {
public:
- BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S)
- : VarDecl(BlockVariable, L, Id, T, S) {}
+ BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+ Decl *PrevDecl)
+ : VarDecl(BlockVariable, L, Id, T, S, PrevDecl) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
@@ -166,8 +178,9 @@
/// pointer to the decl's scope, which is transient).
class FileVarDecl : public VarDecl {
public:
- FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S)
- : VarDecl(FileVariable, L, Id, T, S) {}
+ FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+ Decl *PrevDecl)
+ : VarDecl(FileVariable, L, Id, T, S, PrevDecl) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == FileVariable; }
@@ -177,8 +190,9 @@
/// ParmVarDecl - Represent a parameter to a function.
class ParmVarDecl : public VarDecl {
public:
- ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S)
- : VarDecl(ParmVariable, L, Id, T, S) {}
+ ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+ Decl *PrevDecl)
+ : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
@@ -192,8 +206,9 @@
enum StorageClass {
None, Extern, Static
};
- FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S=None)
- : ValueDecl(Function, L, Id, T),
+ FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+ StorageClass S = None, Decl *PrevDecl)
+ : ValueDecl(Function, L, Id, T, PrevDecl),
ParamInfo(0), Body(0), DeclChain(0), SClass(S) {}
virtual ~FunctionDecl();
@@ -240,8 +255,8 @@
class FieldDecl : public Decl {
QualType DeclType;
public:
- FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
- : Decl(Field, L, Id), DeclType(T) {}
+ FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
+ : Decl(Field, L, Id, PrevDecl), DeclType(T) {}
QualType getType() const { return DeclType; }
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
@@ -260,8 +275,9 @@
class EnumConstantDecl : public ValueDecl {
Expr *Init; // an integer constant expression
public:
- EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E)
- : ValueDecl(EnumConstant, L, Id, T), Init(E) {}
+ EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
+ Decl *PrevDecl)
+ : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
@@ -280,8 +296,8 @@
Type *TypeForDecl;
friend class ASTContext;
protected:
- TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
- : Decl(DK, L, Id), TypeForDecl(0) {}
+ TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
public:
// Implement isa/cast/dyncast/etc.
@@ -296,8 +312,8 @@
/// UnderlyingType - This is the type the typedef is set to.
QualType UnderlyingType;
public:
- TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
- : TypeDecl(Typedef, L, Id), UnderlyingType(T) {}
+ TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
+ : TypeDecl(Typedef, L, Id, PrevDecl), UnderlyingType(T) {}
QualType getUnderlyingType() const { return UnderlyingType; }
@@ -313,7 +329,8 @@
/// it is a declaration ("struct foo;").
bool IsDefinition : 1;
protected:
- TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id) : TypeDecl(DK, L, Id) {
+ TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : TypeDecl(DK, L, Id, PrevDecl) {
IsDefinition = false;
}
public:
@@ -351,7 +368,8 @@
EnumConstantDecl **Elements; // Null if not defined.
int NumElements; // -1 if not defined.
public:
- EnumDecl(SourceLocation L, IdentifierInfo *Id) : TagDecl(Enum, L, Id) {
+ EnumDecl(SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : TagDecl(Enum, L, Id, PrevDecl) {
Elements = 0;
NumElements = -1;
}
@@ -379,7 +397,8 @@
FieldDecl **Members; // Null if not defined.
int NumMembers; // -1 if not defined.
public:
- RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id) :TagDecl(DK, L, Id){
+ RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : TagDecl(DK, L, Id, PrevDecl) {
HasFlexibleArrayMember = false;
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
Members = 0;
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=39623&r1=39622&r2=39623&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:46:21 2007
@@ -98,6 +98,12 @@
return 0;
}
+ /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
+ /// gives the actions implementation a chance to process the group as a whole.
+ virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
+ return Group;
+ }
+
/// ParseStartOfFunctionDef - This is called at the start of a function
/// definition, instead of calling ParseDeclarator. The Declarator includes
/// information about formal arguments that are part of this function.
More information about the cfe-commits
mailing list