build TypedefDecl objects when parsing typedefs.

Add a parsing fastpath for when we see typedef at the top-level.

llvm-svn: 39182
This commit is contained in:
Chris Lattner
2006-11-19 02:31:38 +00:00
parent 33e8a55ed0
commit 302b4be4c2
11 changed files with 111 additions and 50 deletions

View File

@@ -60,6 +60,9 @@ public:
StmtTy *Body);
virtual void PopScope(SourceLocation Loc, Scope *S);
Decl *ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl);
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.

View File

@@ -25,25 +25,48 @@ bool Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
}
void Sema::PopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
Decl *D = II.getFETokenInfo<Decl>();
assert(D && "This decl didn't get pushed??");
Decl *Next = D->getNext();
// FIXME: Push the decl on the parent function list if in a function.
// FIXME: Don't delete the decl when it gets popped!
delete D;
II.setFETokenInfo(Next);
}
}
Action::DeclTy *
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
DeclTy *LastInGroup) {
TypeRef DeclaratorType = GetTypeForDeclarator(D, S);
// FIXME: Temporary.
if (!DeclaratorType.isNull())
DeclaratorType.dump();
IdentifierInfo *II = D.getIdentifier();
Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
Decl *PrevDecl = 0;
if (II) {
PrevDecl = II->getFETokenInfo<Decl>();
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
}
Decl *New;
if (D.isFunctionDeclarator())
if (D.getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef) {
New = ParseTypedefDecl(S, D, PrevDecl);
} else if (D.isFunctionDeclarator())
New = new FunctionDecl(II, D, PrevDecl);
else
New = new VarDecl(II, D, PrevDecl);
if (!New) return 0;
// If this has an identifier, add it to the scope stack.
if (II) {
// If PrevDecl includes conflicting name here, emit a diagnostic.
@@ -68,19 +91,10 @@ Sema::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
return FD;
}
void Sema::PopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
Decl *D = II.getFETokenInfo<Decl>();
assert(D && "This decl didn't get pushed??");
Decl *Next = D->getNext();
// FIXME: Push the decl on the parent function list if in a function.
delete D;
II.setFETokenInfo(Next);
}
Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl) {
assert(D.getIdentifier());
return new TypedefDecl(D.getIdentifier(), D, PrevDecl);
}

View File

@@ -121,9 +121,15 @@ TypeRef Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
}
Sema::TypeResult Sema::ParseTypeName(Scope *S, Declarator &D) {
// FIXME: Validate Declarator.
// C99 6.7.6: Type names have no identifier. This is already validated by
// the parser.
assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
TypeRef T = GetTypeForDeclarator(D, S);
// If the type of the declarator was invalid, this is an invalid typename.
if (T.isNull())
return true;
return T.getAsOpaquePtr();
}

View File

@@ -71,7 +71,7 @@ void Parser::ParseAttributes() {
/// ParseDeclaration - Parse a full 'declaration', which consists of
/// declaration-specifiers, some number of declarators, and a semicolon.
/// 'Context' should be a Declarator::TheContext value.
void Parser::ParseDeclaration(unsigned Context) {
Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
// Parse the common declaration-specifiers piece.
DeclSpec DS;
ParseDeclarationSpecifiers(DS);
@@ -80,6 +80,7 @@ void Parser::ParseDeclaration(unsigned Context) {
// declaration-specifiers init-declarator-list[opt] ';'
if (Tok.getKind() == tok::semi) {
// TODO: emit error on 'int;' or 'const enum foo;'.
// TODO: emit error on 'typedef int;'
// if (!DS.isMissingDeclaratorOk()) Diag(...);
// TODO: Register 'struct foo;' with the type system as an opaque struct.
@@ -87,13 +88,15 @@ void Parser::ParseDeclaration(unsigned Context) {
// that conflicts.
ConsumeToken();
return;
// TODO: Return type definition.
return 0;
}
Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
ParseDeclarator(DeclaratorInfo);
ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
}
/// ParseInitDeclaratorListAfterFirstDeclarator - Parse 'declaration' after

View File

@@ -318,6 +318,9 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
case tok::plus:
ParseObjCClassMethodDeclaration();
return 0;
case tok::kw_typedef:
// A function definition cannot start with a 'typedef' keyword.
return ParseDeclaration(Declarator::FileContext);
default:
// We can't tell whether this is a function-definition or declaration yet.
return ParseDeclarationOrFunctionDefinition();
@@ -345,10 +348,11 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() {
// declaration-specifiers init-declarator-list[opt] ';'
if (Tok.getKind() == tok::semi) {
// TODO: emit error on 'int;' or 'const enum foo;'.
// TODO: emit error on 'typedef int;'
// if (!DS.isMissingDeclaratorOk()) Diag(...);
ConsumeToken();
// TODO: Return type definition.
// TODO: Pass to actions.
return 0;
}

View File

@@ -60,6 +60,9 @@ public:
StmtTy *Body);
virtual void PopScope(SourceLocation Loc, Scope *S);
Decl *ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl);
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.

View File

@@ -25,25 +25,48 @@ bool Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
}
void Sema::PopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
Decl *D = II.getFETokenInfo<Decl>();
assert(D && "This decl didn't get pushed??");
Decl *Next = D->getNext();
// FIXME: Push the decl on the parent function list if in a function.
// FIXME: Don't delete the decl when it gets popped!
delete D;
II.setFETokenInfo(Next);
}
}
Action::DeclTy *
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
DeclTy *LastInGroup) {
TypeRef DeclaratorType = GetTypeForDeclarator(D, S);
// FIXME: Temporary.
if (!DeclaratorType.isNull())
DeclaratorType.dump();
IdentifierInfo *II = D.getIdentifier();
Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
Decl *PrevDecl = 0;
if (II) {
PrevDecl = II->getFETokenInfo<Decl>();
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
}
Decl *New;
if (D.isFunctionDeclarator())
if (D.getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef) {
New = ParseTypedefDecl(S, D, PrevDecl);
} else if (D.isFunctionDeclarator())
New = new FunctionDecl(II, D, PrevDecl);
else
New = new VarDecl(II, D, PrevDecl);
if (!New) return 0;
// If this has an identifier, add it to the scope stack.
if (II) {
// If PrevDecl includes conflicting name here, emit a diagnostic.
@@ -68,19 +91,10 @@ Sema::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
return FD;
}
void Sema::PopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
Decl *D = II.getFETokenInfo<Decl>();
assert(D && "This decl didn't get pushed??");
Decl *Next = D->getNext();
// FIXME: Push the decl on the parent function list if in a function.
delete D;
II.setFETokenInfo(Next);
}
Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl) {
assert(D.getIdentifier());
return new TypedefDecl(D.getIdentifier(), D, PrevDecl);
}

View File

@@ -121,9 +121,15 @@ TypeRef Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
}
Sema::TypeResult Sema::ParseTypeName(Scope *S, Declarator &D) {
// FIXME: Validate Declarator.
// C99 6.7.6: Type names have no identifier. This is already validated by
// the parser.
assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
TypeRef T = GetTypeForDeclarator(D, S);
// If the type of the declarator was invalid, this is an invalid typename.
if (T.isNull())
return true;
return T.getAsOpaquePtr();
}

View File

@@ -138,7 +138,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
DE06BECA0A854E4B0050E87E /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Parse/Scope.h; sourceTree = "<group>"; };
DE06D42F0A8BB52D0050E87E /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = Parse/Parser.cpp; sourceTree = "<group>"; };

View File

@@ -58,6 +58,14 @@ public:
virtual const FunctionDecl *isFunctionDecl() const { return 0; }
};
class TypedefDecl : public Decl {
public:
// FIXME: Remove Declarator argument.
TypedefDecl(IdentifierInfo *Id, const Declarator &D, Decl *Next)
: Decl(Id, D, Next) {}
};
/// FunctionDecl - An instance of this class is created to represent a function
/// declaration or definition.
class FunctionDecl : public Decl {

View File

@@ -318,7 +318,7 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.7: Declarations.
void ParseDeclaration(unsigned Context);
DeclTy *ParseDeclaration(unsigned Context);
DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
void ParseDeclarationSpecifiers(DeclSpec &DS);
void ParseSpecifierQualifierList(DeclSpec &DS);