bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc, SourceLocation ColonColonLoc, CXXScopeSpec &SS) { CXXRecordDecl *RD = nullptr; for (Scope *S = getCurScope(); S; S = S->getParent()) { if (S->isFunctionScope()) { if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S->getEntity())) RD = MD->getParent(); break; } if (S->isClassScope()) { RD = cast<CXXRecordDecl>(S->getEntity()); break; } } if (!RD) { Diag(SuperLoc, diag::err_invalid_super_scope); return true; } else if (RD->isLambda()) { Diag(SuperLoc, diag::err_super_in_lambda_unsupported); return true; } else if (RD->getNumBases() == 0) { Diag(SuperLoc, diag::err_no_base_classes) << RD->getName(); return true; } SS.MakeSuper(Context, RD, SuperLoc, ColonColonLoc); return false; }
bool DynamicIDHandler::IsDynamicLookup (LookupResult& R, Scope* S) { if (R.getLookupKind() != Sema::LookupOrdinaryName) return false; if (R.isForRedeclaration()) return false; // FIXME: Figure out better way to handle: // C++ [basic.lookup.classref]p1: // In a class member access expression (5.2.5), if the . or -> token is // immediately followed by an identifier followed by a <, the // identifier must be looked up to determine whether the < is the // beginning of a template argument list (14.2) or a less-than operator. // The identifier is first looked up in the class of the object // expression. If the identifier is not found, it is then looked up in // the context of the entire postfix-expression and shall name a class // or function template. // // We want to ignore object(.|->)member<template> if (m_Sema->PP.LookAhead(0).getKind() == tok::less) // TODO: check for . or -> in the cached token stream return false; for (Scope* DepScope = S; DepScope; DepScope = DepScope->getParent()) { if (DeclContext* Ctx = static_cast<DeclContext*>(DepScope->getEntity())) { return !Ctx->isDependentContext(); } } return true; }
/// \brief Determines the active Scope associated with the given declaration /// context. /// /// This routine maps a declaration context to the active Scope object that /// represents that declaration context in the parser. It is typically used /// from "scope-less" code (e.g., template instantiation, lazy creation of /// declarations) that injects a name for name-lookup purposes and, therefore, /// must update the Scope. /// /// \returns The scope corresponding to the given declaraion context, or NULL /// if no such scope is open. Scope *Sema::getScopeForContext(DeclContext *Ctx) { if (!Ctx) return 0; Ctx = Ctx->getPrimaryContext(); for (Scope *S = getCurScope(); S; S = S->getParent()) { // Ignore scopes that cannot have declarations. This is important for // out-of-line definitions of static class members. if (S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) if (DeclContext *Entity = static_cast<DeclContext *> (S->getEntity())) if (Ctx == Entity->getPrimaryContext()) return S; } return 0; }
void DeclExtractor::EnforceInitOrder(llvm::SmallVectorImpl<Stmt*>& Stmts){ Scope* TUScope = m_Sema->TUScope; DeclContext* TUDC = static_cast<DeclContext*>(TUScope->getEntity()); // We can't PushDeclContext, because we don't have scope. Sema::ContextRAII pushedDC(*m_Sema, TUDC); std::string FunctionName = "__fd"; createUniqueName(FunctionName); IdentifierInfo& IIFD = m_Context->Idents.get(FunctionName); SourceLocation Loc; NamedDecl* ND = m_Sema->ImplicitlyDefineFunction(Loc, IIFD, TUScope); if (FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(ND)) { FD->setImplicit(false); // Better for debugging // Add a return statement if it doesn't exist if (!isa<ReturnStmt>(Stmts.back())) { Sema::ContextRAII pushedDC(*m_Sema, FD); // Generate the return statement: // First a literal 0, then the return taking that literal. // One bit is enough: llvm::APInt ZeroInt(m_Context->getIntWidth(m_Context->IntTy), 0, /*isSigned=*/true); IntegerLiteral* ZeroLit = IntegerLiteral::Create(*m_Context, ZeroInt, m_Context->IntTy, SourceLocation()); Stmts.push_back(m_Sema->ActOnReturnStmt(ZeroLit->getExprLoc(), ZeroLit).take()); } // Wrap Stmts into a function body. llvm::ArrayRef<Stmt*> StmtsRef(Stmts.data(), Stmts.size()); CompoundStmt* CS = new (*m_Context)CompoundStmt(*m_Context, StmtsRef, Loc, Loc); FD->setBody(CS); // We know the transaction is closed, but it is safe. getTransaction()->forceAppend(FD); // Create the VarDecl with the init std::string VarName = "__vd"; createUniqueName(VarName); IdentifierInfo& IIVD = m_Context->Idents.get(VarName); VarDecl* VD = VarDecl::Create(*m_Context, TUDC, Loc, Loc, &IIVD, FD->getReturnType(), (TypeSourceInfo*)0, SC_None); LookupResult R(*m_Sema, FD->getDeclName(), Loc, Sema::LookupMemberName); R.addDecl(FD); CXXScopeSpec CSS; Expr* UnresolvedLookup = m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).take(); Expr* TheCall = m_Sema->ActOnCallExpr(TUScope, UnresolvedLookup, Loc, MultiExprArg(), Loc).take(); assert(VD && TheCall && "Missing VD or its init!"); VD->setInit(TheCall); // We know the transaction is closed, but it is safe. getTransaction()->forceAppend(VD); // Add it to the transaction for codegenning TUDC->addHiddenDecl(VD); Stmts.clear(); return; } llvm_unreachable("Must be able to enforce init order."); }