|  | //===--- MinimalAction.cpp - Implement the MinimalAction class ------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file was developed by Chris Lattner and is distributed under | 
|  | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | //  This file implements the MinimalAction interface. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "clang/Parse/Parser.h" | 
|  | #include "clang/Parse/DeclSpec.h" | 
|  | #include "clang/Parse/Scope.h" | 
|  | using namespace clang; | 
|  |  | 
|  | /// TypeNameInfo - A link exists here for each scope that an identifier is | 
|  | /// defined. | 
|  | struct TypeNameInfo { | 
|  | TypeNameInfo *Prev; | 
|  | bool isTypeName; | 
|  |  | 
|  | TypeNameInfo(bool istypename, TypeNameInfo *prev) { | 
|  | isTypeName = istypename; | 
|  | Prev = prev; | 
|  | } | 
|  | }; | 
|  |  | 
|  | void MinimalAction:: ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { | 
|  | TUScope = S; | 
|  | IdentifierInfo *II; | 
|  | TypeNameInfo *TI; | 
|  |  | 
|  | // recognize the ObjC built-in type identifiers. | 
|  | II = &Idents.get("id"); | 
|  | TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>()); | 
|  | II->setFETokenInfo(TI); | 
|  | II = &Idents.get("SEL"); | 
|  | TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>()); | 
|  | II->setFETokenInfo(TI); | 
|  | II = &Idents.get("Class"); | 
|  | TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>()); | 
|  | II->setFETokenInfo(TI); | 
|  | } | 
|  |  | 
|  | /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to | 
|  | /// determine whether the name is a type name (objc class name or typedef) or | 
|  | /// not in this scope. | 
|  | Action::DeclTy * | 
|  | MinimalAction::isTypeName(const IdentifierInfo &II, Scope *S) const { | 
|  | if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>()) | 
|  | if (TI->isTypeName) | 
|  | return TI; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /// ActOnDeclarator - If this is a typedef declarator, we modify the | 
|  | /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is | 
|  | /// popped. | 
|  | Action::DeclTy * | 
|  | MinimalAction::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) { | 
|  | IdentifierInfo *II = D.getIdentifier(); | 
|  |  | 
|  | // If there is no identifier associated with this declarator, bail out. | 
|  | if (II == 0) return 0; | 
|  |  | 
|  | TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>(); | 
|  | bool isTypeName = | 
|  | D.getDeclSpec().getStorageClassSpec() == 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; | 
|  | } | 
|  |  | 
|  | Action::DeclTy * | 
|  | MinimalAction::ActOnStartClassInterface(SourceLocation AtInterafceLoc, | 
|  | IdentifierInfo *ClassName, SourceLocation ClassLoc, | 
|  | IdentifierInfo *SuperName, SourceLocation SuperLoc, | 
|  | IdentifierInfo **ProtocolNames, unsigned NumProtocols, | 
|  | SourceLocation EndProtoLoc, AttributeList *AttrList) { | 
|  | TypeNameInfo *TI = | 
|  | new TypeNameInfo(1, ClassName->getFETokenInfo<TypeNameInfo>()); | 
|  |  | 
|  | ClassName->setFETokenInfo(TI); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /// ActOnForwardClassDeclaration - | 
|  | /// Scope will always be top level file scope. | 
|  | Action::DeclTy * | 
|  | MinimalAction::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, | 
|  | IdentifierInfo **IdentList, unsigned NumElts) { | 
|  | for (unsigned i = 0; i != NumElts; ++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. | 
|  | TUScope->AddDecl(IdentList[i]); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /// ActOnPopScope - When a scope is popped, if any typedefs are now out-of-scope, | 
|  | /// they are removed from the IdentifierInfo::FETokenInfo field. | 
|  | void MinimalAction::ActOnPopScope(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); | 
|  | TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>(); | 
|  | assert(TI && "This decl didn't get pushed??"); | 
|  |  | 
|  | if (TI) { | 
|  | TypeNameInfo *Next = TI->Prev; | 
|  | delete TI; | 
|  |  | 
|  | II.setFETokenInfo(Next); | 
|  | } | 
|  | } | 
|  | } |