DeclContext *DeclContext::getEnclosingNamespaceContext() { DeclContext *Ctx = this; // Skip through non-namespace, non-translation-unit contexts. while (!Ctx->isFileContext() || Ctx->isTransparentContext()) Ctx = Ctx->getParent(); return Ctx->getPrimaryContext(); }
CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange, bool KnownDependent) { DeclContext *DC = CurContext; while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) DC = DC->getParent(); // Start constructing the lambda class. CXXRecordDecl *Class = CXXRecordDecl::CreateLambda(Context, DC, IntroducerRange.getBegin(), KnownDependent); DC->addDecl(Class); return Class; }
/// \brief Find the current instantiation that associated with the given type. static CXXRecordDecl * getCurrentInstantiationOf(ASTContext &Context, DeclContext *CurContext, QualType T) { if (T.isNull()) return 0; T = Context.getCanonicalType(T).getUnqualifiedType(); for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getLookupParent()) { // If we've hit a namespace or the global scope, then the // nested-name-specifier can't refer to the current instantiation. if (Ctx->isFileContext()) return 0; // Skip non-class contexts. CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx); if (!Record) continue; // If this record type is not dependent, if (!Record->isDependentType()) return 0; // C++ [temp.dep.type]p1: // // In the definition of a class template, a nested class of a // class template, a member of a class template, or a member of a // nested class of a class template, a name refers to the current // instantiation if it is // -- the injected-class-name (9) of the class template or // nested class, // -- in the definition of a primary class template, the name // of the class template followed by the template argument // list of the primary template (as described below) // enclosed in <>, // -- in the definition of a nested class of a class template, // the name of the nested class referenced as a member of // the current instantiation, or // -- in the definition of a partial specialization, the name // of the class template followed by the template argument // list of the partial specialization enclosed in <>. If // the nth template parameter is a parameter pack, the nth // template argument is a pack expansion (14.6.3) whose // pattern is the name of the parameter pack. // (FIXME: parameter packs) // // All of these options come down to having the // nested-name-specifier type that is equivalent to the // injected-class-name of one of the types that is currently in // our context. if (Context.getCanonicalType(Context.getTypeDeclType(Record)) == T) return Record; if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { QualType InjectedClassName = Template->getInjectedClassNameType(Context); if (T == Context.getCanonicalType(InjectedClassName)) return Template->getTemplatedDecl(); } // FIXME: check for class template partial specializations } return 0; }