FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend, SourceLocation FriendL, ArrayRef<TemplateParameterList*> FriendTypeTPLists) { #ifndef NDEBUG if (Friend.is<NamedDecl*>()) { NamedDecl *D = Friend.get<NamedDecl*>(); assert(isa<FunctionDecl>(D) || isa<CXXRecordDecl>(D) || isa<FunctionTemplateDecl>(D) || isa<ClassTemplateDecl>(D)); // As a temporary hack, we permit template instantiation to point // to the original declaration when instantiating members. assert(D->getFriendObjectKind() || (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind())); // These template parameters are for friend types only. assert(FriendTypeTPLists.size() == 0); } #endif std::size_t Size = sizeof(FriendDecl) + FriendTypeTPLists.size() * sizeof(TemplateParameterList*); void *Mem = C.Allocate(Size); FriendDecl *FD = new (Mem) FriendDecl(DC, L, Friend, FriendL, FriendTypeTPLists); cast<CXXRecordDecl>(DC)->pushFriendDecl(FD); return FD; }
/// checkUndefinedInternals - Check for undefined objects with internal linkage. static void checkUndefinedInternals(Sema &S) { if (S.UndefinedInternals.empty()) return; // Collect all the still-undefined entities with internal linkage. SmallVector<UndefinedInternal, 16> undefined; for (llvm::MapVector<NamedDecl*,SourceLocation>::iterator i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end(); i != e; ++i) { NamedDecl *decl = i->first; // Ignore attributes that have become invalid. if (decl->isInvalidDecl()) continue; // If we found out that the decl is external, don't warn. if (decl->getLinkage() == ExternalLinkage) continue; // __attribute__((weakref)) is basically a definition. if (decl->hasAttr<WeakRefAttr>()) continue; if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) { if (fn->isPure() || fn->hasBody()) continue; } else { if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly) continue; } S.Diag(decl->getLocation(), diag::warn_undefined_internal) << isa<VarDecl>(decl) << decl; S.Diag(i->second, diag::note_used_here); } }
bool VisitCallExpr(CallExpr *E) { llvm::errs() << "I see a CallExpr\n"; E->dump(); Expr *callee = E->getCallee(); if (ImplicitCastExpr *ica = llvm::dyn_cast<ImplicitCastExpr>(callee)) { callee = ica->getSubExpr(); } if (DeclRefExpr *dref = llvm::dyn_cast<DeclRefExpr>(callee)) { llvm::errs() << "declref:\n"; dref->dump(); NamedDecl *d = dref->getFoundDecl(); ASTContext &Context = d->getASTContext(); SourceManager &SM = Context.getSourceManager(); if (dref->hasQualifier()) { llvm::errs() << " has qualifier in name.\n"; NestedNameSpecifierLoc lc = dref->getQualifierLoc(); llvm::errs() << " begin loc: " << lc.getBeginLoc().printToString(SM) << "\n"; llvm::errs() << " end loc: " << lc.getEndLoc().printToString(SM) << "\n"; } if (UsingShadowDecl *sh = llvm::dyn_cast<UsingShadowDecl>(d)) { NamedDecl *td = sh->getTargetDecl(); FoundRealDecl(td); //d->dump(); } else { FoundRealDecl(d); //d->dump(); } } else if (UnresolvedLookupExpr *ule = dyn_cast<UnresolvedLookupExpr>(callee)) { llvm::errs() << "unresolved\n"; ASTContext* Context; SourceManager* SM; for (const auto *d : ule->decls()) { FoundRealDecl(d); Context = &d->getASTContext(); SM = &Context->getSourceManager(); } llvm::errs() << " begin loc: " << ule->getLocStart().printToString(*SM) << "\n"; llvm::errs() << " end loc: " << ule->getLocEnd().printToString(*SM) << "\n"; NestedNameSpecifierLoc ll = ule->getQualifierLoc(); llvm::errs() << " nested begin loc: " << ll.getBeginLoc().printToString(*SM) << "\n"; llvm::errs() << " nested end loc: " << ll.getEndLoc().printToString(*SM) << "\n"; } return true; }
TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, NamedDecl **Params, unsigned NumParams, SourceLocation RAngleLoc) : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), NumParams(NumParams), ContainsUnexpandedParameterPack(false) { assert(this->NumParams == NumParams && "Too many template parameters"); for (unsigned Idx = 0; Idx < NumParams; ++Idx) { NamedDecl *P = Params[Idx]; begin()[Idx] = P; if (!P->isTemplateParameterPack()) { if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) if (NTTP->getType()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) if (TTP->getTemplateParameters()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; // FIXME: If a default argument contains an unexpanded parameter pack, the // template parameter list does too. } } }
/// Obtains a sorted list of functions that are undefined but ODR-used. void Sema::getUndefinedButUsed( SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) { for (llvm::DenseMap<NamedDecl *, SourceLocation>::iterator I = UndefinedButUsed.begin(), E = UndefinedButUsed.end(); I != E; ++I) { NamedDecl *ND = I->first; // Ignore attributes that have become invalid. if (ND->isInvalidDecl()) continue; // __attribute__((weakref)) is basically a definition. if (ND->hasAttr<WeakRefAttr>()) continue; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { if (FD->isDefined()) continue; if (FD->hasExternalLinkage() && !FD->getMostRecentDecl()->isInlined()) continue; } else { if (cast<VarDecl>(ND)->hasDefinition() != VarDecl::DeclarationOnly) continue; if (ND->hasExternalLinkage()) continue; } Undefined.push_back(std::make_pair(ND, I->second)); } // Sort (in order of use site) so that we're not dependent on the iteration // order through an llvm::DenseMap. std::sort(Undefined.begin(), Undefined.end(), SortUndefinedButUsed(Context.getSourceManager())); }
/// Look up the std::nothrow object. static Expr *buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc) { NamespaceDecl *Std = S.getStdNamespace(); assert(Std && "Should already be diagnosed"); LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc, Sema::LookupOrdinaryName); if (!S.LookupQualifiedName(Result, Std)) { // FIXME: <experimental/coroutine> should have been included already. // If we require it to include <new> then this diagnostic is no longer // needed. S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found); return nullptr; } // FIXME: Mark the variable as ODR used. This currently does not work // likely due to the scope at in which this function is called. auto *VD = Result.getAsSingle<VarDecl>(); if (!VD) { Result.suppressDiagnostics(); // We found something weird. Complain about the first thing we found. NamedDecl *Found = *Result.begin(); S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow); return nullptr; } ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc); if (DR.isInvalid()) return nullptr; return DR.get(); }
static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) { if (E->getType() == Ctx.UnknownAnyTy) return (isa<FunctionDecl>(E->getMemberDecl()) ? Cl::CL_PRValue : Cl::CL_LValue); // Handle C first, it's easier. if (!Ctx.getLangOpts().CPlusPlus) { // C99 6.5.2.3p3 // For dot access, the expression is an lvalue if the first part is. For // arrow access, it always is an lvalue. if (E->isArrow()) return Cl::CL_LValue; // ObjC property accesses are not lvalues, but get special treatment. Expr *Base = E->getBase()->IgnoreParens(); if (isa<ObjCPropertyRefExpr>(Base)) return Cl::CL_SubObjCPropertySetting; return ClassifyInternal(Ctx, Base); } NamedDecl *Member = E->getMemberDecl(); // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2. // C++ [expr.ref]p4: If E2 is declared to have type "reference to T", then // E1.E2 is an lvalue. if (ValueDecl *Value = dyn_cast<ValueDecl>(Member)) if (Value->getType()->isReferenceType()) return Cl::CL_LValue; // Otherwise, one of the following rules applies. // -- If E2 is a static member [...] then E1.E2 is an lvalue. if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord()) return Cl::CL_LValue; // -- If E2 is a non-static data member [...]. If E1 is an lvalue, then // E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue; // otherwise, it is a prvalue. if (isa<FieldDecl>(Member)) { // *E1 is an lvalue if (E->isArrow()) return Cl::CL_LValue; Expr *Base = E->getBase()->IgnoreParenImpCasts(); if (isa<ObjCPropertyRefExpr>(Base)) return Cl::CL_SubObjCPropertySetting; return ClassifyInternal(Ctx, E->getBase()); } // -- If E2 is a [...] member function, [...] // -- If it refers to a static member function [...], then E1.E2 is an // lvalue; [...] // -- Otherwise [...] E1.E2 is a prvalue. if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) return Method->isStatic() ? Cl::CL_LValue : Cl::CL_MemberFunction; // -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue. // So is everything else we haven't handled yet. return Cl::CL_PRValue; }
void EvaluateTSynthesizer::Transform() { if (!getTransaction()->getCompilationOpts().DynamicScoping) return; // include the DynamicLookup specific builtins if (!m_EvalDecl) { TemplateDecl* D = cast_or_null<TemplateDecl>(m_Interpreter->LookupDecl("cling"). LookupDecl("runtime"). LookupDecl("internal"). LookupDecl("EvaluateT"). getSingleDecl()); assert(D && "Cannot find EvaluateT TemplateDecl!\n"); m_EvalDecl = dyn_cast<FunctionDecl>(D->getTemplatedDecl()); assert (m_EvalDecl && "The Eval function not found!"); } if (m_NoRange.isInvalid()) { NamespaceDecl* NSD = utils::Lookup::Namespace(m_Sema, "cling"); NSD = utils::Lookup::Namespace(m_Sema, "runtime", NSD); NSD = utils::Lookup::Namespace(m_Sema, "internal", NSD); DeclarationName Name = &m_Context->Idents.get( "InterpreterGeneratedCodeDiagnosticsMaybeIncorrect"); LookupResult R(*m_Sema, Name, SourceLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); m_Sema->LookupQualifiedName(R, NSD); assert(!R.empty() && "Cannot find PrintValue(...)"); NamedDecl* ND = R.getFoundDecl(); m_NoRange = ND->getSourceRange(); m_NoSLoc = m_NoRange.getBegin(); m_NoELoc = m_NoRange.getEnd(); } for (Transaction::const_iterator I = getTransaction()->decls_begin(), E = getTransaction()->decls_end(); I != E; ++I) for (DeclGroupRef::const_iterator J = (*I).begin(), JE = (*I).end(); J != JE; ++J) if (ShouldVisit(*J) && (*J)->hasBody()) { if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*J)) { // Set the decl context, which is needed by Evaluate. m_CurDeclContext = FD->getDeclContext(); ASTNodeInfo NewBody = Visit((*J)->getBody()); FD->setBody(NewBody.getAsSingleNode()); } assert ((!isa<BlockDecl>(*J) || !isa<ObjCMethodDecl>(*J)) && "Not implemented yet!"); } //TODO: Check for error before returning. }
void RedundantLocalVariableRule::apply(CXCursor& node, CXCursor& parentNode, ViolationSet& violationSet) { Stmt *stmt = CursorHelper::getStmt(node); Stmt *parentStmt = CursorHelper::getStmt(parentNode); if (stmt && parentStmt) { NamedDecl *returnDeclRef = extractFromReturnStmt(stmt); NamedDecl *namedDecl = extractFromDeclStmt(parentStmt); if (returnDeclRef && namedDecl && returnDeclRef->getName().equals(namedDecl->getName())) { Violation violation(node, this); violationSet.addViolation(violation); } } }
void IdentifierResolver::iterator::incrementSlowCase() { NamedDecl *D = **this; void *InfoPtr = D->getDeclName().getFETokenInfo<void>(); assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?"); IdDeclInfo *Info = toIdDeclInfo(InfoPtr); BaseIter I = getIterator(); if (I != Info->decls_begin()) *this = iterator(I-1); else // No more decls. *this = iterator(); }
/// \brief Called when an expression computing the size of a parameter pack /// is parsed. /// /// \code /// template<typename ...Types> struct count { /// static const unsigned value = sizeof...(Types); /// }; /// \endcode /// // /// \param OpLoc The location of the "sizeof" keyword. /// \param Name The name of the parameter pack whose size will be determined. /// \param NameLoc The source location of the name of the parameter pack. /// \param RParenLoc The location of the closing parentheses. ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, SourceLocation NameLoc, SourceLocation RParenLoc) { // C++0x [expr.sizeof]p5: // The identifier in a sizeof... expression shall name a parameter pack. LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); LookupName(R, S); NamedDecl *ParameterPack = 0; ParameterPackValidatorCCC Validator; switch (R.getResultKind()) { case LookupResult::Found: ParameterPack = R.getFoundDecl(); break; case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, 0, Validator)) { std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); ParameterPack = Corrected.getCorrectionDecl(); Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest) << &Name << CorrectedQuotedStr << FixItHint::CreateReplacement( NameLoc, Corrected.getAsString(getLangOpts())); Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here) << CorrectedQuotedStr; } case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: break; case LookupResult::Ambiguous: DiagnoseAmbiguousLookup(R); return ExprError(); } if (!ParameterPack || !ParameterPack->isParameterPack()) { Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) << &Name; return ExprError(); } MarkAnyDeclReferenced(OpLoc, ParameterPack, true); return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc, ParameterPack, NameLoc, RParenLoc); }
void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { Out << "#pragma omp threadprivate"; if (!D->varlist_empty()) { for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), E = D->varlist_end(); I != E; ++I) { Out << (I == D->varlist_begin() ? '(' : ','); NamedDecl *ND = cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl()); ND->printQualifiedName(Out); } Out << ")"; } }
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity) { const CXXRecordDecl *NamingClass = Entity.getNamingClass(); const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0); S.Diag(Loc, Entity.getDiag()) << (Entity.getAccess() == AS_protected) << (D ? D->getDeclName() : DeclarationName()) << S.Context.getTypeDeclType(NamingClass) << S.Context.getTypeDeclType(DeclaringClass); DiagnoseAccessPath(S, EC, Entity); }
bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const { assert(UseUnqualifiedMatch); if (Node.getIdentifier()) { // Simple name. return Name == Node.getName(); } if (Node.getDeclName()) { // Name needs to be constructed. llvm::SmallString<128> NodeName; llvm::raw_svector_ostream OS(NodeName); Node.printName(OS); return Name == OS.str(); } return false; }
// With -fcuda-host-device-constexpr, an unattributed constexpr function is // treated as implicitly __host__ __device__, unless: // * it is a variadic function (device-side variadic functions are not // allowed), or // * a __device__ function with this signature was already declared, in which // case in which case we output an error, unless the __device__ decl is in a // system header, in which case we leave the constexpr function unattributed. // // In addition, all function decls are treated as __host__ __device__ when // ForceCUDAHostDeviceDepth > 0 (corresponding to code within a // #pragma clang force_cuda_host_device_begin/end // pair). void Sema::maybeAddCUDAHostDeviceAttrs(Scope *S, FunctionDecl *NewD, const LookupResult &Previous) { assert(getLangOpts().CUDA && "Should only be called during CUDA compilation"); if (ForceCUDAHostDeviceDepth > 0) { if (!NewD->hasAttr<CUDAHostAttr>()) NewD->addAttr(CUDAHostAttr::CreateImplicit(Context)); if (!NewD->hasAttr<CUDADeviceAttr>()) NewD->addAttr(CUDADeviceAttr::CreateImplicit(Context)); return; } if (!getLangOpts().CUDAHostDeviceConstexpr || !NewD->isConstexpr() || NewD->isVariadic() || NewD->hasAttr<CUDAHostAttr>() || NewD->hasAttr<CUDADeviceAttr>() || NewD->hasAttr<CUDAGlobalAttr>()) return; // Is D a __device__ function with the same signature as NewD, ignoring CUDA // attributes? auto IsMatchingDeviceFn = [&](NamedDecl *D) { if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(D)) D = Using->getTargetDecl(); FunctionDecl *OldD = D->getAsFunction(); return OldD && OldD->hasAttr<CUDADeviceAttr>() && !OldD->hasAttr<CUDAHostAttr>() && !IsOverload(NewD, OldD, /* UseMemberUsingDeclRules = */ false, /* ConsiderCudaAttrs = */ false); }; auto It = llvm::find_if(Previous, IsMatchingDeviceFn); if (It != Previous.end()) { // We found a __device__ function with the same name and signature as NewD // (ignoring CUDA attrs). This is an error unless that function is defined // in a system header, in which case we simply return without making NewD // host+device. NamedDecl *Match = *It; if (!getSourceManager().isInSystemHeader(Match->getLocation())) { Diag(NewD->getLocation(), diag::err_cuda_unattributed_constexpr_cannot_overload_device) << NewD->getName(); Diag(Match->getLocation(), diag::note_cuda_conflicting_device_function_declared_here); } return; } NewD->addAttr(CUDAHostAttr::CreateImplicit(Context)); NewD->addAttr(CUDADeviceAttr::CreateImplicit(Context)); }
/// \brief Called when an expression computing the size of a parameter pack /// is parsed. /// /// \code /// template<typename ...Types> struct count { /// static const unsigned value = sizeof...(Types); /// }; /// \endcode /// // /// \param OpLoc The location of the "sizeof" keyword. /// \param Name The name of the parameter pack whose size will be determined. /// \param NameLoc The source location of the name of the parameter pack. /// \param RParenLoc The location of the closing parentheses. ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, SourceLocation NameLoc, SourceLocation RParenLoc) { // C++0x [expr.sizeof]p5: // The identifier in a sizeof... expression shall name a parameter pack. LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); LookupName(R, S); NamedDecl *ParameterPack = nullptr; switch (R.getResultKind()) { case LookupResult::Found: ParameterPack = R.getFoundDecl(); break; case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, llvm::make_unique<ParameterPackValidatorCCC>(), CTK_ErrorRecovery)) { diagnoseTypo(Corrected, PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, PDiag(diag::note_parameter_pack_here)); ParameterPack = Corrected.getCorrectionDecl(); } case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: break; case LookupResult::Ambiguous: DiagnoseAmbiguousLookup(R); return ExprError(); } if (!ParameterPack || !ParameterPack->isParameterPack()) { Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) << &Name; return ExprError(); } MarkAnyDeclReferenced(OpLoc, ParameterPack, true); return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc, ParameterPack, NameLoc, RParenLoc); }
void DisplayFunction() { if (DisplayedFunction) return; DisplayedFunction = true; // FIXME: Is getCodeDecl() always a named decl? if (isa<FunctionDecl>(getCodeDecl()) || isa<ObjCMethodDecl>(getCodeDecl())) { NamedDecl *ND = cast<NamedDecl>(getCodeDecl()); SourceManager &SM = getContext().getSourceManager(); llvm::cerr << "ANALYZE: " << SM.getPresumedLoc(ND->getLocation()).getFilename() << ' ' << ND->getNameAsString() << '\n'; } }
void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); assert((D->NextInContextAndBits.getPointer() || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. if (D == FirstDecl) { if (D == LastDecl) FirstDecl = LastDecl = 0; else FirstDecl = D->NextInContextAndBits.getPointer(); } else { for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) { assert(I && "decl not found in linked list"); if (I->NextInContextAndBits.getPointer() == D) { I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer()); if (D == LastDecl) LastDecl = I; break; } } } // Mark that D is no longer in the decl chain. D->NextInContextAndBits.setPointer(0); // Remove D from the lookup table if necessary. if (isa<NamedDecl>(D)) { NamedDecl *ND = cast<NamedDecl>(D); // Remove only decls that have a name or registered in the lookup. if (!ND->getDeclName() || ND->isHidden()) return; StoredDeclsMap *Map = D->getDeclContext()->getPrimaryContext()->LookupPtr.getPointer(); if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); #ifndef NDEBUG assert(Pos != Map->end() && "no lookup entry for decl"); #endif if (Pos != Map->end() && (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND) ) Pos->second.remove(ND); } }
void Sema::AddPushedVisibilityAttribute(Decl *D) { if (!VisContext) return; NamedDecl *ND = dyn_cast<NamedDecl>(D); if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) return; VisStack *Stack = static_cast<VisStack*>(VisContext); unsigned rawType = Stack->back().first; if (rawType == NoVisibility) return; VisibilityAttr::VisibilityType type = (VisibilityAttr::VisibilityType) rawType; SourceLocation loc = Stack->back().second; D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); }
/// checkUndefinedInternals - Check for undefined objects with internal linkage. static void checkUndefinedInternals(Sema &S) { if (S.UndefinedInternals.empty()) return; // Collect all the still-undefined entities with internal linkage. SmallVector<UndefinedInternal, 16> undefined; for (llvm::DenseMap<NamedDecl*,SourceLocation>::iterator i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end(); i != e; ++i) { NamedDecl *decl = i->first; // Ignore attributes that have become invalid. if (decl->isInvalidDecl()) continue; // __attribute__((weakref)) is basically a definition. if (decl->hasAttr<WeakRefAttr>()) continue; if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) { if (fn->isPure() || fn->hasBody()) continue; } else { if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly) continue; } // We build a FullSourceLoc so that we can sort with array_pod_sort. FullSourceLoc loc(i->second, S.Context.getSourceManager()); undefined.push_back(UndefinedInternal(decl, loc)); } if (undefined.empty()) return; // Sort (in order of use site) so that we're not (as) dependent on // the iteration order through an llvm::DenseMap. llvm::array_pod_sort(undefined.begin(), undefined.end()); for (SmallVectorImpl<UndefinedInternal>::iterator i = undefined.begin(), e = undefined.end(); i != e; ++i) { NamedDecl *decl = i->decl; S.Diag(decl->getLocation(), diag::warn_undefined_internal) << isa<VarDecl>(decl) << decl; S.Diag(i->useLoc, diag::note_used_here); } }
/// Look up the std::experimental::coroutine_handle<PromiseType>. static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType, SourceLocation Loc) { if (PromiseType.isNull()) return QualType(); NamespaceDecl *StdExp = S.lookupStdExperimentalNamespace(); assert(StdExp && "Should already be diagnosed"); LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_handle"), Loc, Sema::LookupOrdinaryName); if (!S.LookupQualifiedName(Result, StdExp)) { S.Diag(Loc, diag::err_implied_coroutine_type_not_found) << "std::experimental::coroutine_handle"; return QualType(); } ClassTemplateDecl *CoroHandle = Result.getAsSingle<ClassTemplateDecl>(); if (!CoroHandle) { Result.suppressDiagnostics(); // We found something weird. Complain about the first thing we found. NamedDecl *Found = *Result.begin(); S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_handle); return QualType(); } // Form template argument list for coroutine_handle<Promise>. TemplateArgumentListInfo Args(Loc, Loc); Args.addArgument(TemplateArgumentLoc( TemplateArgument(PromiseType), S.Context.getTrivialTypeSourceInfo(PromiseType, Loc))); // Build the template-id. QualType CoroHandleType = S.CheckTemplateIdType(TemplateName(CoroHandle), Loc, Args); if (CoroHandleType.isNull()) return QualType(); if (S.RequireCompleteType(Loc, CoroHandleType, diag::err_coroutine_type_missing_specialization)) return QualType(); return CoroHandleType; }
FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend, SourceLocation FriendL) { #ifndef NDEBUG if (Friend.is<NamedDecl*>()) { NamedDecl *D = Friend.get<NamedDecl*>(); assert(isa<FunctionDecl>(D) || isa<CXXRecordDecl>(D) || isa<FunctionTemplateDecl>(D) || isa<ClassTemplateDecl>(D)); // As a temporary hack, we permit template instantiation to point // to the original declaration when instantiating members. assert(D->getFriendObjectKind() || (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind())); } #endif return new (C) FriendDecl(DC, L, Friend, FriendL); }
/// \brief Give notes for a set of overloads. /// /// A companion to isExprCallable. In cases when the name that the programmer /// wrote was an overloaded function, we may be able to make some guesses about /// plausible overloads based on their return types; such guesses can be handed /// off to this method to be emitted as notes. /// /// \param Overloads - The overloads to note. /// \param FinalNoteLoc - If we've suppressed printing some overloads due to /// -fshow-overloads=best, this is the location to attach to the note about too /// many candidates. Typically this will be the location of the original /// ill-formed expression. static void noteOverloads(Sema &S, const UnresolvedSetImpl &Overloads, const SourceLocation FinalNoteLoc) { int ShownOverloads = 0; int SuppressedOverloads = 0; for (UnresolvedSetImpl::iterator It = Overloads.begin(), DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) { // FIXME: Magic number for max shown overloads stolen from // OverloadCandidateSet::NoteCandidates. if (ShownOverloads >= 4 && S.Diags.getShowOverloads() == Ovl_Best) { ++SuppressedOverloads; continue; } NamedDecl *Fn = (*It)->getUnderlyingDecl(); S.Diag(Fn->getLocation(), diag::note_possible_target_of_call); ++ShownOverloads; } if (SuppressedOverloads) S.Diag(FinalNoteLoc, diag::note_ovl_too_many_candidates) << SuppressedOverloads; }
bool HasNameMatcher::matchesNodeFull(const NamedDecl &Node) const { llvm::SmallString<128> NodeName = StringRef("::"); llvm::raw_svector_ostream OS(NodeName); Node.printQualifiedName(OS); const StringRef FullName = OS.str(); const StringRef Pattern = Name; if (Pattern.startswith("::")) return FullName == Pattern; return FullName.endswith(Pattern) && FullName.drop_back(Pattern.size()).endswith("::"); }
void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); assert((D->NextDeclInContext || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. if (D == FirstDecl) { if (D == LastDecl) FirstDecl = LastDecl = 0; else FirstDecl = D->NextDeclInContext; } else { for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) { assert(I && "decl not found in linked list"); if (I->NextDeclInContext == D) { I->NextDeclInContext = D->NextDeclInContext; if (D == LastDecl) LastDecl = I; break; } } } // Mark that D is no longer in the decl chain. D->NextDeclInContext = 0; // Remove D from the lookup table if necessary. if (isa<NamedDecl>(D)) { NamedDecl *ND = cast<NamedDecl>(D); StoredDeclsMap *Map = getPrimaryContext()->LookupPtr; if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); assert(Pos != Map->end() && "no lookup entry for decl"); Pos->second.remove(ND); } }
/// checkUndefinedButUsed - Check for undefined objects with internal linkage /// or that are inline. static void checkUndefinedButUsed(Sema &S) { if (S.UndefinedButUsed.empty()) return; // Collect all the still-undefined entities with internal linkage. SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined; S.getUndefinedButUsed(Undefined); if (Undefined.empty()) return; for (SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> >::iterator I = Undefined.begin(), E = Undefined.end(); I != E; ++I) { NamedDecl *ND = I->first; if (ND->getLinkage() != ExternalLinkage) { S.Diag(ND->getLocation(), diag::warn_undefined_internal) << isa<VarDecl>(ND) << ND; } else { assert(cast<FunctionDecl>(ND)->getMostRecentDecl()->isInlined() && "used object requires definition but isn't inline or internal?"); S.Diag(ND->getLocation(), diag::warn_undefined_inline) << ND; } if (I->second.isValid()) S.Diag(I->second, diag::note_used_here); } }
///\brief Checks for clashing names when trying to extract a declaration. /// ///\returns true if there is another declaration with the same name bool DeclExtractor::CheckForClashingNames( const llvm::SmallVector<NamedDecl*, 4>& Decls, DeclContext* DC, Scope* S) { for (size_t i = 0; i < Decls.size(); ++i) { NamedDecl* ND = Decls[i]; if (TagDecl* TD = dyn_cast<TagDecl>(ND)) { LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(), Sema::LookupTagName, Sema::ForRedeclaration ); m_Sema->LookupName(Previous, S); // There is no function diagnosing the redeclaration of tags (eg. enums). // So either we have to do it by hand or we can call the top-most // function that does the check. Currently the top-most clang function // doing the checks creates an AST node, which we don't want. if (!CheckTagDeclaration(TD, Previous)) return true; } else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) { LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration ); m_Sema->LookupName(Previous, S); m_Sema->CheckVariableDeclaration(VD, Previous); if (VD->isInvalidDecl()) return true; // This var decl will likely get referenced later; claim that it's used. VD->setIsUsed(); } } return false; }
bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){ if (IdentifierInfo *II = Name.getAsIdentifierInfo()) readingIdentifier(*II); void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) { Name.setFETokenInfo(D); return true; } IdDeclInfo *IDI; if (isDeclPtr(Ptr)) { NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); switch (compareDeclarations(PrevD, D)) { case DMK_Different: break; case DMK_Ignore: return false; case DMK_Replace: Name.setFETokenInfo(D); return true; } Name.setFETokenInfo(nullptr); IDI = &(*IdDeclInfos)[Name]; // If the existing declaration is not visible in translation unit scope, // then add the new top-level declaration first. if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { IDI->AddDecl(D); IDI->AddDecl(PrevD); } else { IDI->AddDecl(PrevD); IDI->AddDecl(D); } return true; } IDI = toIdDeclInfo(Ptr); // See whether this declaration is identical to any existing declarations. // If not, find the right place to insert it. for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(), IEnd = IDI->decls_end(); I != IEnd; ++I) { switch (compareDeclarations(*I, D)) { case DMK_Different: break; case DMK_Ignore: return false; case DMK_Replace: *I = D; return true; } if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) { // We've found a declaration that is not visible from the translation // unit (it's in an inner scope). Insert our declaration here. IDI->InsertDecl(I, D); return true; } } // Add the declaration to the end. IDI->AddDecl(D); return true; }
void gpWalkAST::VisitCXXMemberCallExpr( clang::CXXMemberCallExpr *CE ) { const FunctionDecl * FD = CE->getMethodDecl(); if (!FD) return; std::string mname = FD->getQualifiedNameAsString(); const char *sfile=BR.getSourceManager().getPresumedLoc(CE->getExprLoc()).getFilename(); std::string sname(sfile); if ( ! support::isInterestingLocation(sname) ) return; std::string mdname = ND->getQualifiedNameAsString(); const Expr * IOA = CE->getImplicitObjectArgument(); std::string tname = "getparam-dumper.txt.unsorted"; std::string ps = "const class edm::ParameterSet "; std::string ups = "const class edm::UntrackedParameterSet "; std::string gp = "edm::ParameterSet::getParameter"; std::string gup = "edm::ParameterSet::getUntrackedParameter"; if (mname.substr(0,gp.length()) == gp || mname.substr(0,gup.length()) == gup ) { std::string buf; llvm::raw_string_ostream os(buf); const NamedDecl * nd = llvm::dyn_cast<NamedDecl>(AC->getDecl()); if ( FunctionDecl::classof(ND) ) { os << "function decl '" << nd->getQualifiedNameAsString() ; os << "' this '"<<mdname; } else { os << "constructor decl '" << nd->getQualifiedNameAsString() ; os << "' initializer for member decl '"<<mdname; } clang::LangOptions LangOpts; LangOpts.CPlusPlus = true; clang::PrintingPolicy Policy(LangOpts); os << "' with call args '"; for ( unsigned I=0, E=CE->getNumArgs(); I != E; ++I) { if (I) os <<", "; os << CE->getType().getCanonicalType().getAsString()<<" "; CE->getArg(I)->printPretty(os,0,Policy); } os << "' with implicit object '"; const Expr * E = IOA->IgnoreParenCasts(); QualType QE = E->getType().getCanonicalType(); os << QE.getAsString()<<" "; switch( E->getStmtClass() ) { case Stmt::MemberExprClass: os << dyn_cast<MemberExpr>(E)->getMemberDecl()->getQualifiedNameAsString(); break; case Stmt::DeclRefExprClass: os << dyn_cast<DeclRefExpr>(E)->getDecl()->getQualifiedNameAsString(); break; case Stmt::CXXOperatorCallExprClass: dyn_cast<CXXOperatorCallExpr>(E)->printPretty(os,0,Policy); break; case Stmt::CXXBindTemporaryExprClass: dyn_cast<CXXBindTemporaryExpr>(E)->printPretty(os,0,Policy); break; case Stmt::CXXMemberCallExprClass: dyn_cast<CXXMemberCallExpr>(E)->printPretty(os,0,Policy); break; case Stmt::UnaryOperatorClass: dyn_cast<UnaryOperator>(E)->printPretty(os,0,Policy); break; default: E->printPretty(os,0,Policy); os << " unhandled expr class " <<E->getStmtClassName(); } os<<"'\n"; support::writeLog(os.str(),tname); } return ; }
bool Sema::CheckParameterPacksForExpansion( SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef<UnexpandedParameterPack> Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, Optional<unsigned> &NumExpansions) { ShouldExpand = true; RetainExpansion = false; std::pair<IdentifierInfo *, SourceLocation> FirstPack; bool HaveFirstPack = false; for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(), end = Unexpanded.end(); i != end; ++i) { // Compute the depth and index for this parameter pack. unsigned Depth = 0, Index = 0; IdentifierInfo *Name; bool IsFunctionParameterPack = false; if (const TemplateTypeParmType *TTP = i->first.dyn_cast<const TemplateTypeParmType *>()) { Depth = TTP->getDepth(); Index = TTP->getIndex(); Name = TTP->getIdentifier(); } else { NamedDecl *ND = i->first.get<NamedDecl *>(); if (isa<ParmVarDecl>(ND)) IsFunctionParameterPack = true; else std::tie(Depth, Index) = getDepthAndIndex(ND); Name = ND->getIdentifier(); } // Determine the size of this argument pack. unsigned NewPackSize; if (IsFunctionParameterPack) { // Figure out whether we're instantiating to an argument pack or not. typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation = CurrentInstantiationScope->findInstantiationOf( i->first.get<NamedDecl *>()); if (Instantiation->is<DeclArgumentPack *>()) { // We could expand this function parameter pack. NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); } else { // We can't expand this function parameter pack, so we can't expand // the pack expansion. ShouldExpand = false; continue; } } else { // If we don't have a template argument at this depth/index, then we // cannot expand the pack expansion. Make a note of this, but we still // want to check any parameter packs we *do* have arguments for. if (Depth >= TemplateArgs.getNumLevels() || !TemplateArgs.hasTemplateArgument(Depth, Index)) { ShouldExpand = false; continue; } // Determine the size of the argument pack. NewPackSize = TemplateArgs(Depth, Index).pack_size(); } // C++0x [temp.arg.explicit]p9: // Template argument deduction can extend the sequence of template // arguments corresponding to a template parameter pack, even when the // sequence contains explicitly specified template arguments. if (!IsFunctionParameterPack) { if (NamedDecl *PartialPack = CurrentInstantiationScope->getPartiallySubstitutedPack()){ unsigned PartialDepth, PartialIndex; std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); if (PartialDepth == Depth && PartialIndex == Index) RetainExpansion = true; } } if (!NumExpansions) { // The is the first pack we've seen for which we have an argument. // Record it. NumExpansions = NewPackSize; FirstPack.first = Name; FirstPack.second = i->second; HaveFirstPack = true; continue; } if (NewPackSize != *NumExpansions) { // C++0x [temp.variadic]p5: // All of the parameter packs expanded by a pack expansion shall have // the same number of arguments specified. if (HaveFirstPack) Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) << FirstPack.first << Name << *NumExpansions << NewPackSize << SourceRange(FirstPack.second) << SourceRange(i->second); else Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) << Name << *NumExpansions << NewPackSize << SourceRange(i->second); return true; } } return false; }