[cfe-commits] r39292 - in /cfe/cfe/trunk: AST/Sema.h AST/SemaDecl.cpp Parse/ParseDecl.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/Parser.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:42:35 PDT 2007
Author: sabre
Date: Wed Jul 11 11:42:35 2007
New Revision: 39292
URL: http://llvm.org/viewvc/llvm-project?rev=39292&view=rev
Log:
create field decl objects for the members of a struct/union. Diagnose code
like:
struct S { struct S {} X; };
with:
t.c:2:19: error: nested redefinition of 'struct'
struct S { struct S {} X; };
^
t.c:2:1: error: previous definition is here
struct S { struct S {} X; };
^
Modified:
cfe/cfe/trunk/AST/Sema.h
cfe/cfe/trunk/AST/SemaDecl.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/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Parse/Action.h
cfe/cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:42:35 2007
@@ -86,7 +86,11 @@
virtual DeclTy *ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc);
-
+ virtual DeclTy *ParseField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth);
+ virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
+ DeclTy **Fields, unsigned NumFields);
+
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.
Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:42:35 2007
@@ -14,6 +14,7 @@
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
@@ -263,10 +264,10 @@
}
-/// ParseStructUnionTag - This is invoked when we see 'struct foo' or
-/// 'struct {'. In the former case, Name will be non-null. In the later case,
-/// Name will be null. TagType indicates what kind of tag this is. TK indicates
-/// whether this is a reference/declaration/definition of a tag.
+/// ParseTag - This is invoked when we see 'struct foo' or 'struct {'. In the
+/// former case, Name will be non-null. In the later case, Name will be null.
+/// TagType indicates what kind of tag this is. TK indicates whether this is a
+/// reference/declaration/definition of a tag.
Sema::DeclTy *Sema::ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc) {
@@ -315,7 +316,7 @@
// Okay, this is definition of a previously declared or referenced tag.
// Move the location of the decl to be the definition site.
PrevDecl->setLocation(NameLoc);
- PrevDecl->setDefinition(true);
+ //PrevDecl->setDefinition(true);
return PrevDecl;
}
}
@@ -336,8 +337,8 @@
else
assert(0 && "Enum tags not implemented yet!");
- if (TK == TK_Definition)
- New->setDefinition(true);
+ //if (TK == TK_Definition)
+ // New->setDefinition(true);
// If this has an identifier, add it to the scope stack.
if (Name) {
@@ -348,3 +349,50 @@
return New;
}
+
+/// ParseField - Each field of a struct/union/class is passed into this in order
+/// to create a FieldDecl object for it.
+Sema::DeclTy *Sema::ParseField(Scope *S, DeclTy *TagDecl,
+ SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth) {
+ IdentifierInfo *II = D.getIdentifier();
+ Expr *BitWidth = (Expr*)BitfieldWidth;
+
+ SourceLocation Loc = DeclStart;
+ if (II) Loc = D.getIdentifierLoc();
+
+ if (BitWidth) {
+ // TODO: Validate.
+ assert(0 && "bitfields unimp");
+
+ // 6.7.2.1p3
+ // 6.7.2.1p4
+
+ } else {
+ // Not a bitfield.
+
+ // validate II.
+
+ }
+
+ return new FieldDecl(Loc, II, GetTypeForDeclarator(D, S));
+}
+
+void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
+ DeclTy **Fields, unsigned NumFields) {
+ TagDecl *Record = static_cast<TagDecl*>(RecDecl);
+ if (Record->isDefinition()) {
+ // Diagnose code like:
+ // struct S { struct S {} X; };
+ // We discover this when we complete the outer S. Reject and ignore the
+ // outer S.
+ Diag(Record->getLocation(), diag::err_nested_redefinition,
+ Record->getKindName());
+ Diag(RecLoc, diag::err_previous_definition);
+ return;
+ }
+
+ Record->setDefinition(true);
+}
+
+
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:42:35 2007
@@ -453,7 +453,7 @@
// If there is a body, parse it and inform the actions module.
if (Tok.getKind() == tok::l_brace)
- ParseStructUnionBody(TagType, TagDecl);
+ ParseStructUnionBody(StartLoc, TagType, TagDecl);
const char *PrevSpec = 0;
if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagDecl))
@@ -484,7 +484,8 @@
/// declarator[opt] ':' constant-expression
/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
///
-void Parser::ParseStructUnionBody(unsigned TagType, DeclTy *TagDecl) {
+void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
+ unsigned TagType, DeclTy *TagDecl) {
SourceLocation LBraceLoc = ConsumeBrace();
// Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
@@ -493,6 +494,8 @@
Diag(Tok, diag::ext_empty_struct_union_enum,
DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
+ SmallVector<DeclTy*, 32> FieldDecls;
+
// While we still have something to read, read the declarations in the struct.
while (Tok.getKind() != tok::r_brace &&
Tok.getKind() != tok::eof) {
@@ -537,7 +540,9 @@
ParseAttributes();
// Install the declarator into the current TagDecl.
- Actions.ParseField(TagDecl, DeclaratorInfo, BitfieldSize);
+ DeclTy *Field = Actions.ParseField(CurScope, TagDecl, SpecQualLoc,
+ DeclaratorInfo, BitfieldSize);
+ FieldDecls.push_back(Field);
// If we don't have a comma, it is either the end of the list (a ';')
// or an error, bail out.
@@ -564,6 +569,8 @@
}
}
+ Actions.ParseRecordBody(RecordLoc, TagDecl, &FieldDecls[0],FieldDecls.size());
+
MatchRHSPunctuation(tok::r_brace, LBraceLoc);
// If attributes exist after struct contents, parse them.
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:42:35 2007
@@ -86,7 +86,11 @@
virtual DeclTy *ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc);
-
+ virtual DeclTy *ParseField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth);
+ virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
+ DeclTy **Fields, unsigned NumFields);
+
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:42:35 2007
@@ -14,6 +14,7 @@
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
@@ -263,10 +264,10 @@
}
-/// ParseStructUnionTag - This is invoked when we see 'struct foo' or
-/// 'struct {'. In the former case, Name will be non-null. In the later case,
-/// Name will be null. TagType indicates what kind of tag this is. TK indicates
-/// whether this is a reference/declaration/definition of a tag.
+/// ParseTag - This is invoked when we see 'struct foo' or 'struct {'. In the
+/// former case, Name will be non-null. In the later case, Name will be null.
+/// TagType indicates what kind of tag this is. TK indicates whether this is a
+/// reference/declaration/definition of a tag.
Sema::DeclTy *Sema::ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc) {
@@ -315,7 +316,7 @@
// Okay, this is definition of a previously declared or referenced tag.
// Move the location of the decl to be the definition site.
PrevDecl->setLocation(NameLoc);
- PrevDecl->setDefinition(true);
+ //PrevDecl->setDefinition(true);
return PrevDecl;
}
}
@@ -336,8 +337,8 @@
else
assert(0 && "Enum tags not implemented yet!");
- if (TK == TK_Definition)
- New->setDefinition(true);
+ //if (TK == TK_Definition)
+ // New->setDefinition(true);
// If this has an identifier, add it to the scope stack.
if (Name) {
@@ -348,3 +349,50 @@
return New;
}
+
+/// ParseField - Each field of a struct/union/class is passed into this in order
+/// to create a FieldDecl object for it.
+Sema::DeclTy *Sema::ParseField(Scope *S, DeclTy *TagDecl,
+ SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth) {
+ IdentifierInfo *II = D.getIdentifier();
+ Expr *BitWidth = (Expr*)BitfieldWidth;
+
+ SourceLocation Loc = DeclStart;
+ if (II) Loc = D.getIdentifierLoc();
+
+ if (BitWidth) {
+ // TODO: Validate.
+ assert(0 && "bitfields unimp");
+
+ // 6.7.2.1p3
+ // 6.7.2.1p4
+
+ } else {
+ // Not a bitfield.
+
+ // validate II.
+
+ }
+
+ return new FieldDecl(Loc, II, GetTypeForDeclarator(D, S));
+}
+
+void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
+ DeclTy **Fields, unsigned NumFields) {
+ TagDecl *Record = static_cast<TagDecl*>(RecDecl);
+ if (Record->isDefinition()) {
+ // Diagnose code like:
+ // struct S { struct S {} X; };
+ // We discover this when we complete the outer S. Reject and ignore the
+ // outer S.
+ Diag(Record->getLocation(), diag::err_nested_redefinition,
+ Record->getKindName());
+ Diag(RecLoc, diag::err_previous_definition);
+ return;
+ }
+
+ Record->setDefinition(true);
+}
+
+
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=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:42:35 2007
@@ -29,7 +29,7 @@
class Decl {
public:
enum Kind {
- Typedef, Function, Variable,
+ Typedef, Function, Variable, Field,
Struct, Union, Class, Enum
};
@@ -185,6 +185,17 @@
static bool classof(const FunctionDecl *D) { return true; }
};
+
+/// FunctionDecl - An instance of this class is created to represent a function
+/// declaration or definition.
+class FieldDecl : public ObjectDecl {
+
+public:
+ FieldDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T)
+ : ObjectDecl(Field, L, Id, T) {}
+
+};
+
/// TagDecl - Represents the declaration of a struct/union/class/enum.
class TagDecl : public Decl {
/// IsDefinition - True if this is a definition ("struct foo {};"), false if
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=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:42:35 2007
@@ -427,6 +427,8 @@
"use of undeclared identifier '%s'")
DIAG(err_redefinition, ERROR,
"redefinition of '%s'")
+DIAG(err_nested_redefinition, ERROR,
+ "nested redefinition of '%s'")
DIAG(err_use_with_wrong_tag, ERROR,
"use of '%s' with tag type that does not match previous declaration")
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=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:42:35 2007
@@ -153,8 +153,13 @@
return 0;
}
- virtual void ParseField(DeclTy *TagDecl, Declarator &D,
- ExprTy *BitfieldWidth) {}
+ virtual DeclTy *ParseField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth) {
+ return 0;
+ }
+ virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
+ DeclTy **Fields, unsigned NumFields) {}
+
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks.
Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=39292&r1=39291&r2=39292&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:42:35 2007
@@ -333,7 +333,8 @@
void ParseEnumSpecifier(DeclSpec &DS);
void ParseStructUnionSpecifier(DeclSpec &DS);
- void ParseStructUnionBody(unsigned TagType, DeclTy *TagDecl);
+ void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
+ DeclTy *TagDecl);
bool isDeclarationSpecifier() const;
bool isTypeSpecifierQualifier() const;
More information about the cfe-commits
mailing list