/// LookupBuiltin - Lookup for built-in functions static bool LookupBuiltin(Sema &S, LookupResult &R) { Sema::LookupNameKind NameKind = R.getLookupKind(); // If we didn't find a use of this identifier, and if the identifier // corresponds to a compiler builtin, create the defn object for the builtin // now, injecting it into system scope, and return it. if (NameKind == Sema::LookupOrdinaryName) { IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo(); if (II) { // If this is a builtin on this (or all) targets, create the defn. if (unsigned BuiltinID = II->getBuiltinID()) { if (NamedDefn *D = S.LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, S.BaseWorkspace, /*R.isForRedeclaration()*/false, R.getNameLoc())) { R.addDefn(D); return true; } //FIXME yabin // should i deal with this situation in gmat? // if (R.isForRedeclaration()) { // // If we're redeclaring this function anyway, forget that // // this was a builtin at all. // S.Context.BuiltinInfo.ForgetBuiltin(BuiltinID, // S.Context.Idents); // } return false; } } } 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; }
bool Sema::OOPLookupName(LookupResult &R, Scope *S) { assert(getLangOptions().OOP && "Can perform only OOP lookup"); DefinitionName Name = R.getLookupName(); IdentifierResolver::iterator I = IdResolver.begin(Name), IEnd = IdResolver.end(); // First we lookup local scope. for (; S /*&& !isNamespaceOrTranslationUnitScope(S)*/; S = S->getParent()) { DefnContext *Ctx = static_cast<DefnContext *>(S->getEntity()); // Check whether the IdResolver has anything in this scope. bool Found = false; for (; I != IEnd && S->isDefnScope(*I); ++I) { if (R.isAcceptableDefn(*I)) { Found = true; R.addDefn(*I); } } if (Found) { R.resolveKind(); if (S->isClassScope()) if (UserClassDefn *Record = dyn_cast_or_null<UserClassDefn>(Ctx)) R.setNamingClass(Record); return true; } if (Ctx) { for (; Ctx; Ctx = Ctx->getParent()) { // We do not look directly into function or method contexts, // since all of the local variables and parameters of the // function/method are present within the Scope. if (Ctx->isFunctionOrMethod()) { continue; } // Perform qualified name lookup into this context. // FIXME: In some cases, we know that every name that could be found by // this qualified name lookup will also be on the identifier chain. For // example, inside a class without any base classes, we never need to // perform qualified lookup because all of the members are on top of the // identifier chain. if (LookupQualifiedName(R, Ctx, /*InUnqualifiedLookup=*/true)) return true; } } } // Stop if we ran out of scopes. // FIXME: This really, really shouldn't be happening. if (!S) return false; // If we are looking for members, no need to look into global/namespace scope. if (R.getLookupKind() == LookupMemberName) return false; return !R.empty(); }
// Returns true on failure. static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, //SourceRange BaseRange, const StructType *STy, SourceLocation OpLoc) { StructTypeDecl *SDecl = STy->getDecl(); DeclContext *DC = SDecl; // The record definition is complete, now look up the member. SemaRef.LookupQualifiedName(R, DC); if (!R.empty()) return false; #if 0 // We didn't find anything with the given name, so try to correct // for typos. DeclarationName Name = R.getLookupName(); RecordMemberExprValidatorCCC Validator; TypoCorrection Corrected = SemaRef.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), NULL, &SS, Validator, DC); R.clear(); if (NamedDecl *ND = Corrected.getCorrectionDecl()) { std::string CorrectedStr( Corrected.getAsString(SemaRef.getLangOpts())); std::string CorrectedQuotedStr( Corrected.getQuoted(SemaRef.getLangOpts())); R.setLookupName(Corrected.getCorrection()); R.addDecl(ND); SemaRef.Diag(R.getNameLoc(), diag::err_no_member_suggest) << Name << DC << CorrectedQuotedStr << SS.getRange() << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), CorrectedStr); SemaRef.Diag(ND->getLocation(), diag::note_previous_decl) << ND->getDeclName(); } #endif // FIXME: Is this right? (also in clang) return false; }