mirror of
https://github.com/intel/llvm.git
synced 2026-02-03 19:18:13 +08:00
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:
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>"; };
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user