[cfe-commits] r39074 - in /cfe/cfe/trunk: Parse/MinimalAction.cpp Parse/ParseDecl.cpp Parse/ParseStmt.cpp Parse/Parser.cpp include/clang/Parse/Action.h include/clang/Parse/Parser.h
snaroff at cs.uiuc.edu
snaroff at cs.uiuc.edu
Wed Jul 11 09:27:19 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:27:19 2007
New Revision: 39074
URL: http://llvm.org/viewvc/llvm-project?rev=39074&view=rev
Log:
- Added basic structure for parsing top level Objective-C forms.
- Extended the typedef mechanism for classes, improved performance of the common case.
- Implemented @class in the parser.
Modified:
cfe/cfe/trunk/Parse/MinimalAction.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Parse/ParseStmt.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/include/clang/Parse/Action.h
cfe/cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/cfe/trunk/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/MinimalAction.cpp?rev=39074&r1=39073&r2=39074&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/MinimalAction.cpp (original)
+++ cfe/cfe/trunk/Parse/MinimalAction.cpp Wed Jul 11 11:27:19 2007
@@ -17,18 +17,24 @@
using namespace llvm;
using namespace clang;
-/// TypedefInfo - A link exists here for each scope that an identifier is
+/// TypeNameInfo - A link exists here for each scope that an identifier is
/// defined.
-struct TypedefInfo {
- TypedefInfo *Prev;
- bool isTypedef;
+struct TypeNameInfo {
+ TypeNameInfo *Prev;
+ bool isTypeName;
+
+ TypeNameInfo(bool istypename, TypeNameInfo *prev) {
+ isTypeName = istypename;
+ Prev = prev;
+ }
+
};
/// isTypedefName - This looks at the IdentifierInfo::FETokenInfo field to
/// determine whether the name is a typedef or not in this scope.
-bool EmptyAction::isTypedefName(const IdentifierInfo &II, Scope *S) const {
- TypedefInfo *TI = II.getFETokenInfo<TypedefInfo>();
- return TI != 0 && TI->isTypedef;
+bool EmptyAction::isTypeName(const IdentifierInfo &II, Scope *S) const {
+ TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>();
+ return TI != 0 && TI->isTypeName;
}
/// ParseDeclarator - If this is a typedef declarator, we modify the
@@ -37,20 +43,41 @@
Action::DeclTy *
EmptyAction::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
DeclTy *LastInGroup) {
+ IdentifierInfo *II = D.getIdentifier();
+
// If there is no identifier associated with this declarator, bail out.
- if (D.getIdentifier() == 0) return 0;
+ if (II == 0) return 0;
- // Remember whether or not this declarator is a typedef.
- TypedefInfo *TI = new TypedefInfo();
- TI->isTypedef = D.getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
-
- // Add this to the linked-list hanging off the identifier.
- IdentifierInfo &II = *D.getIdentifier();
- TI->Prev = II.getFETokenInfo<TypedefInfo>();
- II.setFETokenInfo(TI);
+ TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>();
+ bool isTypeName = D.getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
+
+ // this check avoids creating TypeNameInfo objects for the common case.
+ // It does need to handle the uncommon case of shadowing a typedef name with a
+ // non-typedef name. e.g. { typedef int a; a xx; { int a; } }
+ if (weCurrentlyHaveTypeInfo || isTypeName) {
+ TypeNameInfo *TI = new TypeNameInfo(isTypeName, weCurrentlyHaveTypeInfo);
+
+ II->setFETokenInfo(TI);
+
+ // Remember that this needs to be removed when the scope is popped.
+ S->AddDecl(II);
+ }
+ return 0;
+}
+
+// Scope will always be top level file scope.
+
+Action::DeclTy *
+EmptyAction::ParsedClassDeclaration(Scope *S,
+ IdentifierInfo **identList, unsigned nElements) {
+ for (unsigned i = 0; i < nElements; i++) {
+ TypeNameInfo *TI = new TypeNameInfo(1, identList[i]->getFETokenInfo<TypeNameInfo>());
+
+ identList[i]->setFETokenInfo(TI);
- // Remember that this needs to be removed when the scope is popped.
- S->AddDecl(&II);
+ // Remember that this needs to be removed when the scope is popped.
+ S->AddDecl(identList[i]);
+ }
return 0;
}
@@ -60,12 +87,14 @@
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
- TypedefInfo *TI = II.getFETokenInfo<TypedefInfo>();
+ TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>();
assert(TI && "This decl didn't get pushed??");
-
- TypedefInfo *Next = TI->Prev;
- delete TI;
- II.setFETokenInfo(Next);
+ if (TI) {
+ TypeNameInfo *Next = TI->Prev;
+ delete TI;
+
+ II.setFETokenInfo(Next);
+ }
}
}
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39074&r1=39073&r2=39074&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:27:19 2007
@@ -262,7 +262,7 @@
DS.TypeSpecComplex == DeclSpec::TSC_unspecified &&
DS.TypeSpecSign == DeclSpec::TSS_unspecified &&
// It has to be available as a typedef too!
- Actions.isTypedefName(*Tok.getIdentifierInfo(), CurScope)) {
+ Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, PrevSpec);
break;
}
@@ -645,7 +645,7 @@
// typedef-name
case tok::identifier:
- return Actions.isTypedefName(*Tok.getIdentifierInfo(), CurScope);
+ return Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
// TODO: Attributes.
}
@@ -698,7 +698,7 @@
// typedef-name
case tok::identifier:
- return Actions.isTypedefName(*Tok.getIdentifierInfo(), CurScope);
+ return Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
// TODO: Attributes.
}
}
@@ -923,7 +923,7 @@
HasPrototype = false;
IsEmpty = true;
} else if (Tok.getKind() == tok::identifier &&
- !Actions.isTypedefName(*Tok.getIdentifierInfo(), CurScope)) {
+ !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
// Identifier list. Note that '(' identifier-list ')' is only allowed for
// normal declarators, not for abstract-declarators.
assert(D.isPastIdentifier() && "Identifier (if present) must be passed!");
Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=39074&r1=39073&r2=39074&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:27:19 2007
@@ -205,7 +205,7 @@
// Check to see if this is a declaration.
if (!OnlyStatement &&
- Actions.isTypedefName(*IdentTok.getIdentifierInfo(), CurScope)) {
+ Actions.isTypeName(*IdentTok.getIdentifierInfo(), CurScope)) {
// Handle this. Warn/disable if in middle of block and !C99.
DeclSpec DS;
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=39074&r1=39073&r2=39074&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:27:19 2007
@@ -287,6 +287,15 @@
"top-level asm block");
// TODO: Invoke action for top-level asm.
return 0;
+ case tok::at:
+ ObjCParseAtDirectives();
+ return 0;
+ case tok::minus:
+ ObjCParseInstanceMethodDeclaration();
+ return 0;
+ case tok::plus:
+ ObjCParseClassMethodDeclaration();
+ return 0;
default:
// We can't tell whether this is a function-definition or declaration yet.
return ParseDeclarationOrFunctionDefinition();
@@ -443,3 +452,69 @@
MatchRHSPunctuation(tok::r_paren, Loc);
}
+
+void Parser::ObjCParseAtDirectives() {
+ SourceLocation atLoc = ConsumeToken(); // the "@"
+
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ if (II == 0) return; // Not an identifier.
+
+ switch (II->getObjCKeywordID()) {
+ case tok::objc_class:
+ ObjCParseClassDeclaration(atLoc);
+ case tok::objc_interface:
+ ObjCParseInterfaceDeclaration();
+ case tok::objc_protocol:
+ ObjCParseProtocolDeclaration();
+ case tok::objc_implementation:
+ ObjCParseImplementationDeclaration();
+ case tok::objc_end:
+ ObjCParseEndDeclaration();
+ case tok::objc_compatibility_alias:
+ ObjCParseAliasDeclaration();
+ default:
+ ; // TODO: need to issue a diagnostic...
+ }
+}
+
+///
+/// objc-class-declaration:
+/// @class identifier-list ;
+///
+void Parser::ObjCParseClassDeclaration(SourceLocation atLoc) {
+ ConsumeToken(); // the identifier "class"
+ SmallVector<IdentifierInfo *, 8> classNames;
+
+ while (1) {
+ if (Tok.getKind() == tok::identifier) {
+ classNames.push_back(Tok.getIdentifierInfo());
+ } else {
+ Diag(diag::err_expected_ident);
+ }
+ ConsumeToken();
+ if (Tok.getKind() == tok::comma)
+ ConsumeToken();
+ else
+ break;
+ }
+ if (Tok.getKind() == tok::semi) {
+ SourceLocation semiLoc = ConsumeToken();
+ Actions.ParsedClassDeclaration(CurScope,&classNames[0],classNames.size());
+ }
+}
+void Parser::ObjCParseInterfaceDeclaration() {
+}
+void Parser::ObjCParseProtocolDeclaration() {
+}
+void Parser::ObjCParseImplementationDeclaration() {
+}
+void Parser::ObjCParseEndDeclaration() {
+}
+void Parser::ObjCParseAliasDeclaration() {
+}
+
+void Parser::ObjCParseInstanceMethodDeclaration() {
+}
+
+void Parser::ObjCParseClassMethodDeclaration() {
+}
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=39074&r1=39073&r2=39074&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:27:19 2007
@@ -35,7 +35,7 @@
/// the parser has just done or is about to do when the method is called. They
/// are not requests that the actions module do the specified action.
///
-/// All of the methods here are optional except isTypedefName(), which must be
+/// All of the methods here are optional except isTypeName(), which must be
/// specified in order for the parse to complete accurately. The EmptyAction
/// class does this bare-minimum of tracking to implement this functionality.
class Action {
@@ -78,9 +78,9 @@
// Symbol Table Tracking Callbacks.
//===--------------------------------------------------------------------===//
- /// isTypedefName - Return true if the specified identifier is a typedef name
+ /// isTypeName - Return true if the specified identifier is a typedef name
/// in the current scope.
- virtual bool isTypedefName(const IdentifierInfo &II, Scope *S) const = 0;
+ virtual bool isTypeName(const IdentifierInfo &II, Scope *S) const = 0;
/// ParseDeclarator - This callback is invoked when a declarator is parsed and
/// 'Init' specifies the initializer if any. This is for things like:
@@ -111,6 +111,11 @@
// 'External Declaration' (Top Level) Parsing Callbacks.
//===--------------------------------------------------------------------===//
+ virtual DeclTy *ParsedClassDeclaration(Scope *S,
+ IdentifierInfo **identList, unsigned nElements) {
+ return 0;
+ }
+
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks.
//===--------------------------------------------------------------------===//
@@ -271,9 +276,9 @@
/// to reimplement all of the scoping rules.
class EmptyAction : public Action {
public:
- /// isTypedefName - This looks at the IdentifierInfo::FETokenInfo field to
+ /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to
/// determine whether the name is a typedef or not in this scope.
- virtual bool isTypedefName(const IdentifierInfo &II, Scope *S) const;
+ virtual bool isTypeName(const IdentifierInfo &II, Scope *S) const;
/// ParseDeclarator - If this is a typedef declarator, we modify the
/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
@@ -284,6 +289,10 @@
/// PopScope - When a scope is popped, if any typedefs are now out-of-scope,
/// they are removed from the IdentifierInfo::FETokenInfo field.
virtual void PopScope(SourceLocation Loc, Scope *S);
+
+ virtual DeclTy *ParsedClassDeclaration(Scope *S,
+ IdentifierInfo **identList, unsigned nElements);
+
};
} // end namespace clang
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=39074&r1=39073&r2=39074&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:27:19 2007
@@ -231,7 +231,18 @@
DeclTy *ParseFunctionDefinition(Declarator &D);
void ParseSimpleAsm();
void ParseAsmStringLiteral();
-
+
+ // Objective-C External Declarations
+ void ObjCParseAtDirectives();
+ void ObjCParseClassDeclaration(SourceLocation atLoc);
+ void ObjCParseInterfaceDeclaration();
+ void ObjCParseProtocolDeclaration();
+ void ObjCParseImplementationDeclaration();
+ void ObjCParseEndDeclaration();
+ void ObjCParseAliasDeclaration();
+ void ObjCParseInstanceMethodDeclaration();
+ void ObjCParseClassMethodDeclaration();
+
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
More information about the cfe-commits
mailing list