From: Alp Toker Date: Wed, 22 Jan 2014 07:29:52 +0000 (+0000) Subject: Introduce and use Decl::getAsFunction() to simplify templated function checks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=296a4e54995407cf7e3602b29d28ffd001d15e23;p=clang Introduce and use Decl::getAsFunction() to simplify templated function checks Lift the getFunctionDecl() utility out of the parser into a general Decl::getAsFunction() and use it to simplify other parts of the implementation. Reduce isFunctionOrFunctionTemplate() to a simple type check that works the same was as the other is* functions and move unwrapping of shadowed decls to callers so it doesn't get run twice. Shuffle around canSkipFunctionBody() to reduce virtual dispatch on ASTConsumer. There's no need to query when we already know the body can't be skipped. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199794 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index fc6344c8a1..756ceb7858 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -110,7 +110,7 @@ class NamedDecl : public Decl { DeclarationName Name; private: - NamedDecl *getUnderlyingDeclImpl(); + NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index fde90b2d5a..23fb519b16 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -837,7 +837,19 @@ public: bool isTemplateDecl() const; /// \brief Whether this declaration is a function or function template. - bool isFunctionOrFunctionTemplate() const; + bool isFunctionOrFunctionTemplate() const { + return (DeclKind >= Decl::firstFunction && + DeclKind <= Decl::lastFunction) || + DeclKind == FunctionTemplate; + } + + /// \brief Returns the function itself, or the templated function if this is a + /// function template. + FunctionDecl *getAsFunction() LLVM_READONLY; + + const FunctionDecl *getAsFunction() const { + return const_cast(this)->getAsFunction(); + } /// \brief Changes the namespace of this declaration to reflect that it's /// a function-local extern declaration. diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 4d864f2128..aa92805f51 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -561,16 +561,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, if (PrevVar->getStorageClass() == SC_Static) return LinkageInfo::internal(); } - } else if (isa(D) || isa(D)) { + } else if (const FunctionDecl *Function = D->getAsFunction()) { // C++ [temp]p4: // A non-member function template can have internal linkage; any // other template name shall have external linkage. - const FunctionDecl *Function = 0; - if (const FunctionTemplateDecl *FunTmpl - = dyn_cast(D)) - Function = FunTmpl->getTemplatedDecl(); - else - Function = cast(D); // Explicitly declared static. if (Function->getCanonicalDecl()->getStorageClass() == SC_Static) @@ -1456,11 +1450,9 @@ bool NamedDecl::isCXXInstanceMember() const { if (isa(D) || isa(D) || isa(D)) return true; - if (isa(D)) - return cast(D)->isInstance(); - if (isa(D)) - return cast(cast(D) - ->getTemplatedDecl())->isInstance(); + if (const CXXMethodDecl *MD = + dyn_cast_or_null(D->getAsFunction())) + return MD->isInstance(); return false; } diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 46adad6c3c..288d66a205 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -159,11 +159,12 @@ bool Decl::isParameterPack() const { return isTemplateParameterPack(); } -bool Decl::isFunctionOrFunctionTemplate() const { - if (const UsingShadowDecl *UD = dyn_cast(this)) - return UD->getTargetDecl()->isFunctionOrFunctionTemplate(); - - return isa(this) || isa(this); +FunctionDecl *Decl::getAsFunction() { + if (FunctionDecl *FD = dyn_cast(this)) + return FD; + if (const FunctionTemplateDecl *FTD = dyn_cast(this)) + return FTD->getTemplatedDecl(); + return 0; } bool Decl::isTemplateDecl() const { diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 9648e62b11..f344e8cc03 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -1030,13 +1030,9 @@ CXXRecordDecl::getGenericLambdaTemplateParameterList() const { } static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { - QualType T; - if (isa(Conv)) - Conv = cast(Conv)->getTargetDecl(); - if (FunctionTemplateDecl *ConvTemp = dyn_cast(Conv)) - T = ConvTemp->getTemplatedDecl()->getResultType(); - else - T = cast(Conv)->getConversionType(); + QualType T = + cast(Conv->getUnderlyingDecl()->getAsFunction()) + ->getConversionType(); return Context.getCanonicalType(T); } diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 3738c0e4f2..516b60d89b 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -1291,16 +1291,11 @@ static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin, NamedDecl *decl = *begin; if (isa(decl)) return false; - if (isa(decl)) - decl = cast(decl)->getUnderlyingDecl(); // Unresolved member expressions should only contain methods and // method templates. - assert(isa(decl) || isa(decl)); - - if (isa(decl)) - decl = cast(decl)->getTemplatedDecl(); - if (cast(decl)->isStatic()) + if (cast(decl->getUnderlyingDecl()->getAsFunction()) + ->isStatic()) return false; } while (++begin != end); diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 2fc705bc0f..a4b60992a5 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -19,13 +19,6 @@ #include "clang/Sema/Scope.h" using namespace clang; -/// Get the FunctionDecl for a function or function template decl. -static FunctionDecl *getFunctionDecl(Decl *D) { - if (FunctionDecl *fn = dyn_cast(D)) - return fn; - return cast(D)->getTemplatedDecl(); -} - /// ParseCXXInlineMethodDef - We parsed and verified that the specified /// Declarator is a well formed C++ inline method definition. Now lex its body /// and store its tokens for parsing after the C++ class is complete. @@ -109,9 +102,9 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, // the tokens and store them for parsing at the end of the translation unit. if (getLangOpts().DelayedTemplateParsing && DefinitionKind == FDK_Definition && - !D.getDeclSpec().isConstexprSpecified() && - !(FnD && getFunctionDecl(FnD) && - getFunctionDecl(FnD)->getResultType()->getContainedAutoType()) && + !D.getDeclSpec().isConstexprSpecified() && + !(FnD && FnD->getAsFunction() && + FnD->getAsFunction()->getResultType()->getContainedAutoType()) && ((Actions.CurContext->isDependentContext() || (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && TemplateInfo.Kind != ParsedTemplateInfo::ExplicitSpecialization)) && @@ -121,7 +114,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, LexTemplateFunctionForLateParsing(Toks); if (FnD) { - FunctionDecl *FD = getFunctionDecl(FnD); + FunctionDecl *FD = FnD->getAsFunction(); Actions.CheckForFunctionRedefinition(FD); Actions.MarkAsLateParsedTemplate(FD, FnD, Toks); } @@ -173,7 +166,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, // If you remove this, you can remove the code that clears the flag // after parsing the member. if (D.getDeclSpec().isFriendSpecified()) { - FunctionDecl *FD = getFunctionDecl(FnD); + FunctionDecl *FD = FnD->getAsFunction(); Actions.CheckForFunctionRedefinition(FD); FD->setLateTemplateParsed(true); } @@ -456,7 +449,8 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { ParseFunctionStatementBody(LM.D, FnScope); // Clear the late-template-parsed bit if we set it before. - if (LM.D) getFunctionDecl(LM.D)->setLateTemplateParsed(false); + if (LM.D) + LM.D->getAsFunction()->setLateTemplateParsed(false); if (Tok.getLocation() != origLoc) { // Due to parsing error, we either went over the cached tokens or diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index e2a71c5e71..777fd01aa2 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -1227,9 +1227,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { return; // Get the FunctionDecl. - FunctionTemplateDecl *FunTmplD = dyn_cast(LPT.D); - FunctionDecl *FunD = - FunTmplD ? FunTmplD->getTemplatedDecl() : cast(LPT.D); + FunctionDecl *FunD = LPT.D->getAsFunction(); // Track template parameter depth. TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); @@ -1312,8 +1310,10 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { Actions.ActOnDefaultCtorInitializers(LPT.D); if (Tok.is(tok::l_brace)) { - assert((!FunTmplD || FunTmplD->getTemplateParameters()->getDepth() < - TemplateParameterDepth) && + assert((!isa(LPT.D) || + cast(LPT.D) + ->getTemplateParameters() + ->getDepth() < TemplateParameterDepth) && "TemplateParameterDepth should be greater than the depth of " "current template being instantiated!"); ParseFunctionStatementBody(LPT.D, FnScope); diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 316448aa83..abd34fd650 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -1085,12 +1085,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, LexTemplateFunctionForLateParsing(Toks); if (DP) { - FunctionDecl *FnD = 0; - if (FunctionTemplateDecl *FunTmpl = dyn_cast(DP)) - FnD = FunTmpl->getTemplatedDecl(); - else - FnD = cast(DP); - + FunctionDecl *FnD = DP->getAsFunction(); Actions.CheckForFunctionRedefinition(FnD); Actions.MarkAsLateParsedTemplate(FnD, DP, Toks); } diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 7722ba9fe9..c00ad81b09 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1081,15 +1081,15 @@ static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, (isa(D) && isa( cast(D)->getTemplatedDecl()))) { - S.Diag(D->getLocation(), diag::note_access_protected_restricted_ctordtor) - << isa(D); - return true; + return S.Diag(D->getLocation(), + diag::note_access_protected_restricted_ctordtor) + << isa(D->getAsFunction()); } // Otherwise, use the generic diagnostic. - S.Diag(D->getLocation(), diag::note_access_protected_restricted_object) - << S.Context.getTypeDeclType(ECRecord); - return true; + return S.Diag(D->getLocation(), + diag::note_access_protected_restricted_object) + << S.Context.getTypeDeclType(ECRecord); } return false; @@ -1748,10 +1748,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, /// Checks access to the target of a friend declaration. Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) { - assert(isa(target) || - (isa(target) && - isa(cast(target) - ->getTemplatedDecl()))); + assert(isa(target->getAsFunction())); // Friendship lookup is a redeclaration lookup, so there's never an // inheritance path modifying access. @@ -1760,10 +1757,7 @@ Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) { if (!getLangOpts().AccessControl || access == AS_public) return AR_accessible; - CXXMethodDecl *method = dyn_cast(target); - if (!method) - method = cast( - cast(target)->getTemplatedDecl()); + CXXMethodDecl *method = dyn_cast(target->getAsFunction()); assert(method->getQualifier()); AccessTarget entity(Context, AccessTarget::Member, diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 73a758db64..33909c7307 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -660,13 +660,10 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { return C.getObjCInterfaceType(Iface); QualType T; - if (const FunctionDecl *Function = dyn_cast(ND)) + if (const FunctionDecl *Function = ND->getAsFunction()) T = Function->getCallResultType(); else if (const ObjCMethodDecl *Method = dyn_cast(ND)) T = Method->getSendResultType(); - else if (const FunctionTemplateDecl *FunTmpl = - dyn_cast(ND)) - T = FunTmpl->getTemplatedDecl()->getCallResultType(); else if (const EnumConstantDecl *Enumerator = dyn_cast(ND)) T = C.getTypeDeclType(cast(Enumerator->getDeclContext())); else if (const ObjCPropertyDecl *Property = dyn_cast(ND)) @@ -2066,14 +2063,11 @@ static void AddResultTypeChunk(ASTContext &Context, return; // Determine the type of the declaration (if it has a type). - QualType T; - if (const FunctionDecl *Function = dyn_cast(ND)) + QualType T; + if (const FunctionDecl *Function = ND->getAsFunction()) T = Function->getResultType(); else if (const ObjCMethodDecl *Method = dyn_cast(ND)) T = Method->getResultType(); - else if (const FunctionTemplateDecl *FunTmpl = - dyn_cast(ND)) - T = FunTmpl->getTemplatedDecl()->getResultType(); else if (const EnumConstantDecl *Enumerator = dyn_cast(ND)) T = Context.getTypeDeclType(cast(Enumerator->getDeclContext())); else if (isa(ND)) { diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9dac4d5302..949526b3ed 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -845,7 +845,8 @@ Corrected: // seems likely a type is wanted instead of the non-type that was found. bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star); if ((NextToken.is(tok::identifier) || - (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) && + (NextIsOp && + FirstDecl->getUnderlyingDecl()->isFunctionOrFunctionTemplate())) && isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { TypeDecl *Type = Result.getAsSingle(); DiagnoseUseOfDecl(Type, NameLoc); @@ -962,12 +963,9 @@ void Sema::ExitDeclaratorContext(Scope *S) { void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { - FunctionDecl *FD = dyn_cast(D); - if (FunctionTemplateDecl *TFD = dyn_cast_or_null(D)) { - // We assume that the caller has already called - // ActOnReenterTemplateScope - FD = TFD->getTemplatedDecl(); - } + // We assume that the caller has already called + // ActOnReenterTemplateScope so getTemplatedDecl() works. + FunctionDecl *FD = D->getAsFunction(); if (!FD) return; @@ -2270,12 +2268,7 @@ static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) { bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, bool MergeTypeWithOld) { // Verify the old decl was also a function. - FunctionDecl *Old = 0; - if (FunctionTemplateDecl *OldFunctionTemplate - = dyn_cast(OldD)) - Old = OldFunctionTemplate->getTemplatedDecl(); - else - Old = dyn_cast(OldD); + FunctionDecl *Old = OldD->getAsFunction(); if (!Old) { if (UsingShadowDecl *Shadow = dyn_cast(OldD)) { if (New->getFriendObjectKind()) { @@ -7474,10 +7467,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (!getLangOpts().CPlusPlus1y && MD && MD->isConstexpr() && !MD->isStatic() && !isa(MD) && (MD->getTypeQualifiers() & Qualifiers::Const) == 0) { - CXXMethodDecl *OldMD = dyn_cast_or_null(OldDecl); - if (FunctionTemplateDecl *OldTD = - dyn_cast_or_null(OldDecl)) - OldMD = dyn_cast(OldTD->getTemplatedDecl()); + CXXMethodDecl *OldMD = 0; + if (OldDecl) + OldMD = dyn_cast(OldDecl->getAsFunction()); if (!OldMD || !OldMD->isStatic()) { const FunctionProtoType *FPT = MD->getType()->castAs(); @@ -9699,24 +9691,15 @@ void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { } bool Sema::canSkipFunctionBody(Decl *D) { - if (!Consumer.shouldSkipFunctionBody(D)) - return false; - - if (isa(D)) - return true; - - FunctionDecl *FD = 0; - if (FunctionTemplateDecl *FTD = dyn_cast(D)) - FD = FTD->getTemplatedDecl(); - else - FD = cast(D); - // We cannot skip the body of a function (or function template) which is // constexpr, since we may need to evaluate its body in order to parse the // rest of the file. // We cannot skip the body of a function with an undeduced return type, // because any callers of that function need to know the type. - return !FD->isConstexpr() && !FD->getResultType()->isUndeducedType(); + if (const FunctionDecl *FD = D->getAsFunction()) + if (FD->isConstexpr() || FD->getResultType()->isUndeducedType()) + return false; + return Consumer.shouldSkipFunctionBody(D); } Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { @@ -9733,12 +9716,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation) { - FunctionDecl *FD = 0; - FunctionTemplateDecl *FunTmpl = dyn_cast_or_null(dcl); - if (FunTmpl) - FD = FunTmpl->getTemplatedDecl(); - else - FD = dyn_cast_or_null(dcl); + FunctionDecl *FD = dcl ? dcl->getAsFunction() : 0; sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); sema::AnalysisBasedWarnings::Policy *ActivePolicy = 0; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 76b9d669d4..3fe6337d50 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -7242,13 +7242,7 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig, if (FoundEquivalentDecl) return false; - if (Target->isFunctionOrFunctionTemplate()) { - FunctionDecl *FD; - if (isa(Target)) - FD = cast(Target)->getTemplatedDecl(); - else - FD = cast(Target); - + if (FunctionDecl *FD = Target->getAsFunction()) { NamedDecl *OldDecl = 0; switch (CheckOverload(0, FD, Previous, OldDecl, /*IsForUsingDecl*/ true)) { case Ovl_Overload: diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 7b6536973a..0f5a78b10a 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2320,11 +2320,7 @@ void Sema::FindAssociatedClassesAndNamespaces( for (UnresolvedSetIterator I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I) { // Look through any using declarations to find the underlying function. - NamedDecl *Fn = (*I)->getUnderlyingDecl(); - - FunctionDecl *FDecl = dyn_cast(Fn); - if (!FDecl) - FDecl = cast(Fn)->getTemplatedDecl(); + FunctionDecl *FDecl = (*I)->getUnderlyingDecl()->getAsFunction(); // Add the classes and namespaces associated with the parameter // types and return type of this function. @@ -2814,14 +2810,8 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, // operator template, but not both. if (FoundRaw && FoundTemplate) { Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName(); - for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { - Decl *D = *I; - if (UsingShadowDecl *USD = dyn_cast(D)) - D = USD->getTargetDecl(); - if (FunctionTemplateDecl *FunTmpl = dyn_cast(D)) - D = FunTmpl->getTemplatedDecl(); - NoteOverloadCandidate(cast(D)); - } + for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) + NoteOverloadCandidate((*I)->getUnderlyingDecl()->getAsFunction()); return LOLR_Error; } @@ -2853,14 +2843,8 @@ void ADLResult::insert(NamedDecl *New) { } // Otherwise, decide which is a more recent redeclaration. - FunctionDecl *OldFD, *NewFD; - if (isa(New)) { - OldFD = cast(Old)->getTemplatedDecl(); - NewFD = cast(New)->getTemplatedDecl(); - } else { - OldFD = cast(Old); - NewFD = cast(New); - } + FunctionDecl *OldFD = Old->getAsFunction(); + FunctionDecl *NewFD = New->getAsFunction(); FunctionDecl *Cursor = NewFD; while (true) { @@ -3065,8 +3049,8 @@ NamedDecl *VisibleDeclsRecord::checkHidden(NamedDecl *ND) { // Functions and function templates in the same scope overload // rather than hide. FIXME: Look for hiding based on function // signatures! - if ((*I)->isFunctionOrFunctionTemplate() && - ND->isFunctionOrFunctionTemplate() && + if ((*I)->getUnderlyingDecl()->isFunctionOrFunctionTemplate() && + ND->getUnderlyingDecl()->isFunctionOrFunctionTemplate() && SM == ShadowMaps.rbegin()) continue; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 7d35bcabfe..af47cb4bba 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -930,24 +930,15 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord() && !New->getFriendObjectKind(); - if (FunctionTemplateDecl *OldT = dyn_cast(OldD)) { - if (!IsOverload(New, OldT->getTemplatedDecl(), UseMemberUsingDeclRules)) { - if (UseMemberUsingDeclRules && OldIsUsingDecl) { - HideUsingShadowDecl(S, cast(*I)); - continue; - } - - Match = *I; - return Ovl_Match; - } - } else if (FunctionDecl *OldF = dyn_cast(OldD)) { + if (FunctionDecl *OldF = OldD->getAsFunction()) { if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) { if (UseMemberUsingDeclRules && OldIsUsingDecl) { HideUsingShadowDecl(S, cast(*I)); continue; } - if (!shouldLinkPossiblyHiddenDecl(*I, New)) + if (!isa(OldD) && + !shouldLinkPossiblyHiddenDecl(*I, New)) continue; Match = *I; diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 62f58c93d9..f0ef288c5e 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -6267,13 +6267,9 @@ unsigned clang_CXXMethod_isPureVirtual(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; - const CXXMethodDecl *Method = 0; const Decl *D = cxcursor::getCursorDecl(C); - if (const FunctionTemplateDecl *FunTmpl = - dyn_cast_or_null(D)) - Method = dyn_cast(FunTmpl->getTemplatedDecl()); - else - Method = dyn_cast_or_null(D); + const CXXMethodDecl *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : 0; return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0; } @@ -6281,13 +6277,9 @@ unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; - const CXXMethodDecl *Method = 0; const Decl *D = cxcursor::getCursorDecl(C); - if (const FunctionTemplateDecl *FunTmpl = - dyn_cast_or_null(D)) - Method = dyn_cast(FunTmpl->getTemplatedDecl()); - else - Method = dyn_cast_or_null(D); + const CXXMethodDecl *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : 0; return (Method && Method->isStatic()) ? 1 : 0; } @@ -6295,13 +6287,9 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; - const CXXMethodDecl *Method = 0; const Decl *D = cxcursor::getCursorDecl(C); - if (const FunctionTemplateDecl *FunTmpl = - dyn_cast_or_null(D)) - Method = dyn_cast(FunTmpl->getTemplatedDecl()); - else - Method = dyn_cast_or_null(D); + const CXXMethodDecl *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : 0; return (Method && Method->isVirtual()) ? 1 : 0; } } // end: extern "C"