00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/ast/Scope.h"
00010 #include "comma/ast/Decl.h"
00011 #include "comma/basic/IdentifierInfo.h"
00012 #include "llvm/Support/Casting.h"
00013
00014 using namespace comma;
00015
00016 Scope::Scope()
00017 : kind(CUNIT_SCOPE),
00018 parentScope(0),
00019 childScope(0)
00020 {
00021 }
00022
00023 Scope::Scope(ScopeKind kind, Scope *parent)
00024 : kind(kind),
00025 parentScope(parent),
00026 childScope(0)
00027 {
00028 assert(parent->childScope == 0);
00029 parentScope->childScope = this;
00030 }
00031
00032 Scope *Scope::pushScope(ScopeKind kind)
00033 {
00034
00035
00036
00037 return new Scope(kind, this);
00038 }
00039
00040 Scope::DeclInfo *Scope::lookupDeclInfo(IdentifierInfo *idInfo)
00041 {
00042 DeclStack *declStack = idInfo->getMetadata<DeclStack>();
00043
00044 if (declStack && declStack->back().scope != this)
00045 declStack->push_back(DeclInfo(this));
00046 else {
00047 declStack = new DeclStack();
00048 declStack->reserve(4);
00049 declStack->push_back(DeclInfo(this));
00050 idInfo->setMetadata(declStack);
00051 }
00052 return &declStack->back();
00053 }
00054
00055 void Scope::addType(ModelType *type)
00056 {
00057 IdentifierInfo *idInfo = type->getIdInfo();
00058 DeclInfo *declInfo = lookupDeclInfo(type->getIdInfo());
00059
00060 declInfo->type = type;
00061 identifiers.insert(idInfo);
00062 }
00063
00064 ModelType *Scope::lookupType(const IdentifierInfo *info, bool traverse) const
00065 {
00066 if (info->hasMetadata()) {
00067 DeclStack *stack = info->getMetadata<DeclStack>();
00068 DeclInfo *declInfo = &stack->back();
00069
00070 if (declInfo->scope != this && !traverse)
00071 return 0;
00072
00073 if (declInfo->type)
00074 return declInfo->type;
00075
00076 if (traverse) {
00077
00078
00079 DeclStack::iterator iter = stack->end();
00080 DeclStack::iterator endIter = stack->begin();
00081 for (--iter; iter != endIter; --iter) {
00082 if (iter->type != 0)
00083 return iter->type;
00084 }
00085 }
00086 return 0;
00087 }
00088 return 0;
00089 }
00090
00091 Scope *Scope::popScope()
00092 {
00093
00094
00095
00096 IdInfoSet::iterator iter = identifiers.begin();
00097 IdInfoSet::iterator endIter = identifiers.end();
00098 for ( ; iter != endIter; ++iter) {
00099 IdentifierInfo *info = *iter;
00100
00101 DeclStack *declStack = info->getMetadata<DeclStack>();
00102 assert(declStack && "IdInfo metadata corruption?");
00103
00104 DeclInfo *declInfo = &declStack->back();
00105 assert(declInfo->scope == this && "Decl stack corruption?");
00106
00107 declStack->pop_back();
00108 if (declStack->empty()) {
00109 delete declStack;
00110 info->setMetadata(0);
00111 }
00112 }
00113
00114
00115 parentScope->childScope = 0;
00116 return parentScope;
00117 }