Example #1
0
/// 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::LookupUnqualified(LookupResult& R, Scope* S) {

    if (!IsDynamicLookup(R, S))
      return false;

    if (Callbacks && Callbacks->isEnabled()) {
      return Callbacks->LookupObject(R, S);
    }

    DeclarationName Name = R.getLookupName();
    IdentifierInfo* II = Name.getAsIdentifierInfo();
    SourceLocation Loc = R.getNameLoc();
    VarDecl* Result = VarDecl::Create(m_Context,
                                      R.getSema().getFunctionLevelDeclContext(),
                                      Loc,
                                      Loc,
                                      II,
                                      m_Context.DependentTy,
                                      /*TypeSourceInfo*/0,
                                      SC_None,
                                      SC_None);
    if (Result) {
      R.addDecl(Result);
      // Say that we can handle the situation. Clang should try to recover
      return true;
    }
    // We cannot handle the situation. Give up
    return false;
  }
Example #3
0
/// Checks access to all the declarations in the given result set.
void Sema::CheckLookupAccess(const LookupResult &R) {
  assert(getLangOptions().AccessControl
         && "performing access check without access control");
  assert(R.getNamingClass() && "performing access check without naming class");

  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
    if (I.getAccess() != AS_public) {
      AccessTarget Entity(Context, AccessedEntity::Member,
                          R.getNamingClass(), I.getPair(),
                          R.getBaseObjectType());
      Entity.setDiag(diag::err_access);

      CheckAccess(*this, R.getNameLoc(), Entity);
    }
  }
}
  bool SymbolResolverCallback::LookupObject(LookupResult& R, Scope* S) {
    if (!ShouldResolveAtRuntime(R, S))
      return false;

    if (m_IsRuntime) {
      // We are currently parsing an EvaluateT() expression
      if (!m_Resolve)
        return false;

      // Only for demo resolve all unknown objects to cling::test::Tester
      if (!m_TesterDecl) {
        clang::Sema& SemaR = m_Interpreter->getSema();
        clang::NamespaceDecl* NSD = utils::Lookup::Namespace(&SemaR, "cling");
        NSD = utils::Lookup::Namespace(&SemaR, "test", NSD);
        m_TesterDecl = utils::Lookup::Named(&SemaR, "Tester", NSD);
      }
      assert (m_TesterDecl && "Tester not found!");
      R.addDecl(m_TesterDecl);
      return true; // Tell clang to continue.
    }

    // We are currently NOT parsing an EvaluateT() expression.
    // Escape the expression into an EvaluateT() expression.
    ASTContext& C = R.getSema().getASTContext();
    DeclContext* DC = 0;
    // For DeclContext-less scopes like if (dyn_expr) {}
    while (!DC) {
      DC = static_cast<DeclContext*>(S->getEntity());
      S = S->getParent();
    }
    DeclarationName Name = R.getLookupName();
    IdentifierInfo* II = Name.getAsIdentifierInfo();
    SourceLocation Loc = R.getNameLoc();
    VarDecl* Res = VarDecl::Create(C, DC, Loc, Loc, II, C.DependentTy,
        /*TypeSourceInfo*/0, SC_None);

    // Annotate the decl to give a hint in cling. FIXME: Current implementation
    // is a gross hack, because TClingCallbacks shouldn't know about
    // EvaluateTSynthesizer at all!
    SourceRange invalidRange;
    Res->addAttr(new (C) AnnotateAttr(invalidRange, C, "__ResolveAtRuntime", 0));
    R.addDecl(Res);
    DC->addDecl(Res);
    // Say that we can handle the situation. Clang should try to recover
    return true;
  }
Example #5
0
// 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;
}
Example #6
0
/// Look up the given member of the given non-type-dependent
/// expression.  This can return in one of two ways:
///  * If it returns a sentinel null-but-valid result, the caller will
///    assume that lookup was performed and the results written into
///    the provided structure.  It will take over from there.
///  * Otherwise, the returned expression will be produced in place of
///    an ordinary member expression.
Action::OwningExprResult
Sema::LookupMemberExpr(LookupResult &R, Expr &BaseExpr,
                       SourceLocation OpLoc) {

  const Type *BaseType = BaseExpr.getType();
  assert(BaseType);

  SourceLocation MemberLoc = R.getNameLoc();
#if 0
  DeclarationName MemberName = R.getLookupName();

  // For later type-checking purposes, turn arrow accesses into dot
  // accesses.  The only access type we support that doesn't follow
  // the C equivalence "a->b === (*a).b" is ObjC property accesses,
  // and those never use arrows, so this is unaffected.
  if (IsArrow) {
    if (const PointerType *Ptr = BaseType->getAs<PointerType>())
      BaseType = Ptr->getPointeeType();
    else if (BaseType->isRecordType()) {
      // Recover from arrow accesses to records, e.g.:
      //   struct MyRecord foo;
      //   foo->bar
      // This is actually well-formed in C++ if MyRecord has an
      // overloaded operator->, but that should have been dealt with
      // by now.
      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
        << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
        << FixItHint::CreateReplacement(OpLoc, ".");
      IsArrow = false;
    } else if (BaseType->isFunctionType()) {
      goto fail;
    } else {
      Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
        << BaseType << BaseExpr.get()->getSourceRange();
      return ExprError();
    }
  }
#endif
  // spec#Selector: "If x is a pointer to a struct, x.y is shorthand for (*x).y"
  if (const PointerType *P = dyn_cast<PointerType>(BaseType))
    BaseType = P->getPointeeType();

  // Handle field access to simple records.
  if (const StructType *STy = BaseType->getAs<StructType>()) {
    if (LookupMemberExprInRecord(*this, R, //BaseExpr.get()->getSourceRange(),
                                 STy, OpLoc))
      return ExprError();

    // Returning valid-but-null is how we indicate to the caller that
    // the lookup result was filled in.
    return Owned((Expr *)0);
  }

#if 0
  // Failure cases.
 fail:

  // If the user is trying to apply . to a function name, it's probably
  // because they forgot parentheses to call that function.
  if (tryToRecoverWithCall(BaseExpr,
                           PDiag(diag::err_member_reference_needs_call),
                           /*complain*/ false,
                           IsArrow ? &isPointerToRecordType : &isRecordType)) {
    if (BaseExpr.isInvalid())
      return ExprError();
    BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
    return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc);
  }
#endif

  Diag(OpLoc, diag::typecheck_field_reference_struct)
    //<< BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
    << BaseType << SourceRange(MemberLoc, MemberLoc);

  return ExprError();
}
Example #7
0
Action::OwningExprResult
Sema::BuildMemberReferenceExpr(Expr *BaseExpr, const Type *BaseExprType,
                               SourceLocation OpLoc, LookupResult &R) {
  const Type* BaseType = BaseExprType;

  if (const PointerType *P = dyn_cast<PointerType>(BaseType))
    BaseType = P->getPointeeType();
  //R.setBaseObjectType(BaseType);

  //const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
  //DeclarationName MemberName = MemberNameInfo.getName();
  //SourceLocation MemberLoc = MemberNameInfo.getLoc();
  IdentifierInfo *II = R.getLookupName();

  if (R.isAmbiguous())
    return ExprError();

  if (R.empty()) {
    // FIXME: make sure this prints the '*' for pointer-to-struct types (?)
    //DeclContext *DC = BaseType->getAs<StructType>()->getDecl();
    // FIXME: clang prints DC instead of BaseExprType here. Don't do that,
    // else we don't print struct names right. However, make sure ParenTypes
    // get desugared once they exist.
    Diag(R.getNameLoc(), diag::no_field) << II << BaseExprType;
    //Diag(R.getNameLoc(), diag::err_no_member)
      //<< MemberName << DC
      //<< (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
    return ExprError();
  }

  assert(R.isSingleResult());
  NamedDecl *MemberDecl = R.getFoundDecl();
#if 0
  DeclAccessPair FoundDecl = R.begin().getPair();

  // If the decl being referenced had an error, return an error for this
  // sub-expr without emitting another error, in order to avoid cascading
  // error cases.
  if (MemberDecl->isInvalidDecl())
    return ExprError();

  bool ShouldCheckUse = true;
  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MemberDecl)) {
    // Don't diagnose the use of a virtual member function unless it's
    // explicitly qualified.
    if (MD->isVirtual())
      ShouldCheckUse = false;
  }

  // Check the use of this member.
  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc)) {
    Owned(BaseExpr);
    return ExprError();
  }
#endif

  if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
    //return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
                                   //FD, FoundDecl, MemberNameInfo);
    return Owned(BuildMemberExpr(*this, Context, BaseExpr, FD,
                                 R.getNameLoc(), FD->getType()));
  }

#if 0
  if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
    // We may have found a field within an anonymous union or struct
    // (C++ [class.union]).
    return BuildAnonymousStructUnionMemberReference(MemberLoc, FD,
                                                    BaseExpr, OpLoc);

  if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow,
                                 Var, FoundDecl, MemberNameInfo,
                                 Var->getType().getNonReferenceType(),
                                 VK_LValue, OK_Ordinary));
  }

  if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
    ExprValueKind valueKind;
    QualType type;
    if (MemberFn->isInstance()) {
      valueKind = VK_RValue;
      type = Context.BoundMemberTy;
    } else {
      valueKind = VK_LValue;
      type = MemberFn->getType();
    }

    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow,
                                 MemberFn, FoundDecl, 
                                 MemberNameInfo, type, valueKind,
                                 OK_Ordinary));
  }
  assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");

  if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow,
                                 Enum, FoundDecl, MemberNameInfo,
                                 Enum->getType(), VK_RValue, OK_Ordinary));
  }

  Owned(BaseExpr);

  // We found something that we didn't expect. Complain.
  if (isa<TypeDecl>(MemberDecl))
    Diag(MemberLoc, diag::err_typecheck_member_reference_type)
      << MemberName << BaseType << int(IsArrow);
  else
    Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
      << MemberName << BaseType << int(IsArrow);

  Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
    << MemberName;
  R.suppressDiagnostics();
#endif
  return ExprError();
}