summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlp Toker <alp@nuanti.com>2014-01-22 07:29:52 +0000
committerAlp Toker <alp@nuanti.com>2014-01-22 07:29:52 +0000
commita2794f9f363361f87a3538b90b78ff13381d5ce1 (patch)
tree5cc9768890e4532cd0625ba7ffbe54d2c35d5b35 /clang/lib
parent217c640ee85825f734ffce2ff6305e3e29003262 (diff)
downloadbcm5719-llvm-a2794f9f363361f87a3538b90b78ff13381d5ce1.tar.gz
bcm5719-llvm-a2794f9f363361f87a3538b90b78ff13381d5ce1.zip
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. llvm-svn: 199794
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp16
-rw-r--r--clang/lib/AST/DeclBase.cpp11
-rw-r--r--clang/lib/AST/DeclCXX.cpp10
-rw-r--r--clang/lib/AST/ExprCXX.cpp9
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp20
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp10
-rw-r--r--clang/lib/Parse/Parser.cpp7
-rw-r--r--clang/lib/Sema/SemaAccess.cpp22
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp12
-rw-r--r--clang/lib/Sema/SemaDecl.cpp50
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp8
-rw-r--r--clang/lib/Sema/SemaLookup.cpp30
-rw-r--r--clang/lib/Sema/SemaOverload.cpp15
13 files changed, 64 insertions, 156 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4d864f2128c..aa92805f510 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/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<FunctionDecl>(D) || isa<FunctionTemplateDecl>(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<FunctionTemplateDecl>(D))
- Function = FunTmpl->getTemplatedDecl();
- else
- Function = cast<FunctionDecl>(D);
// Explicitly declared static.
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -1456,11 +1450,9 @@ bool NamedDecl::isCXXInstanceMember() const {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
return true;
- if (isa<CXXMethodDecl>(D))
- return cast<CXXMethodDecl>(D)->isInstance();
- if (isa<FunctionTemplateDecl>(D))
- return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D)
- ->getTemplatedDecl())->isInstance();
+ if (const CXXMethodDecl *MD =
+ dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
+ return MD->isInstance();
return false;
}
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 46adad6c3c3..288d66a205a 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -159,11 +159,12 @@ bool Decl::isParameterPack() const {
return isTemplateParameterPack();
}
-bool Decl::isFunctionOrFunctionTemplate() const {
- if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
- return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
-
- return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
+FunctionDecl *Decl::getAsFunction() {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
+ return FD;
+ if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(this))
+ return FTD->getTemplatedDecl();
+ return 0;
}
bool Decl::isTemplateDecl() const {
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 9648e62b11f..f344e8cc03a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1030,13 +1030,9 @@ CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
}
static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
- QualType T;
- if (isa<UsingShadowDecl>(Conv))
- Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl();
- if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv))
- T = ConvTemp->getTemplatedDecl()->getResultType();
- else
- T = cast<CXXConversionDecl>(Conv)->getConversionType();
+ QualType T =
+ cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction())
+ ->getConversionType();
return Context.getCanonicalType(T);
}
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 3738c0e4f2c..516b60d89bc 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1291,16 +1291,11 @@ static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
NamedDecl *decl = *begin;
if (isa<UnresolvedUsingValueDecl>(decl))
return false;
- if (isa<UsingShadowDecl>(decl))
- decl = cast<UsingShadowDecl>(decl)->getUnderlyingDecl();
// Unresolved member expressions should only contain methods and
// method templates.
- assert(isa<CXXMethodDecl>(decl) || isa<FunctionTemplateDecl>(decl));
-
- if (isa<FunctionTemplateDecl>(decl))
- decl = cast<FunctionTemplateDecl>(decl)->getTemplatedDecl();
- if (cast<CXXMethodDecl>(decl)->isStatic())
+ if (cast<CXXMethodDecl>(decl->getUnderlyingDecl()->getAsFunction())
+ ->isStatic())
return false;
} while (++begin != end);
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 2fc705bc0fb..a4b60992a58 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/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<FunctionDecl>(D))
- return fn;
- return cast<FunctionTemplateDecl>(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/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index e2a71c5e716..777fd01aa2a 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1227,9 +1227,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
return;
// Get the FunctionDecl.
- FunctionTemplateDecl *FunTmplD = dyn_cast<FunctionTemplateDecl>(LPT.D);
- FunctionDecl *FunD =
- FunTmplD ? FunTmplD->getTemplatedDecl() : cast<FunctionDecl>(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<FunctionTemplateDecl>(LPT.D) ||
+ cast<FunctionTemplateDecl>(LPT.D)
+ ->getTemplateParameters()
+ ->getDepth() < TemplateParameterDepth) &&
"TemplateParameterDepth should be greater than the depth of "
"current template being instantiated!");
ParseFunctionStatementBody(LPT.D, FnScope);
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 316448aa83f..abd34fd650e 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/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<FunctionTemplateDecl>(DP))
- FnD = FunTmpl->getTemplatedDecl();
- else
- FnD = cast<FunctionDecl>(DP);
-
+ FunctionDecl *FnD = DP->getAsFunction();
Actions.CheckForFunctionRedefinition(FnD);
Actions.MarkAsLateParsedTemplate(FnD, DP, Toks);
}
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 7722ba9fe95..c00ad81b097 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1081,15 +1081,15 @@ static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
(isa<FunctionTemplateDecl>(D) &&
isa<CXXConstructorDecl>(
cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
- S.Diag(D->getLocation(), diag::note_access_protected_restricted_ctordtor)
- << isa<CXXDestructorDecl>(D);
- return true;
+ return S.Diag(D->getLocation(),
+ diag::note_access_protected_restricted_ctordtor)
+ << isa<CXXDestructorDecl>(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<CXXMethodDecl>(target) ||
- (isa<FunctionTemplateDecl>(target) &&
- isa<CXXMethodDecl>(cast<FunctionTemplateDecl>(target)
- ->getTemplatedDecl())));
+ assert(isa<CXXMethodDecl>(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<CXXMethodDecl>(target);
- if (!method)
- method = cast<CXXMethodDecl>(
- cast<FunctionTemplateDecl>(target)->getTemplatedDecl());
+ CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(target->getAsFunction());
assert(method->getQualifier());
AccessTarget entity(Context, AccessTarget::Member,
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 73a758db643..33909c73077 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/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<FunctionDecl>(ND))
+ if (const FunctionDecl *Function = ND->getAsFunction())
T = Function->getCallResultType();
else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
T = Method->getSendResultType();
- else if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast<FunctionTemplateDecl>(ND))
- T = FunTmpl->getTemplatedDecl()->getCallResultType();
else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(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<FunctionDecl>(ND))
+ QualType T;
+ if (const FunctionDecl *Function = ND->getAsFunction())
T = Function->getResultType();
else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
T = Method->getResultType();
- else if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast<FunctionTemplateDecl>(ND))
- T = FunTmpl->getTemplatedDecl()->getResultType();
else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
else if (isa<UnresolvedUsingValueDecl>(ND)) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9dac4d53024..949526b3edf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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<TypeDecl>();
DiagnoseUseOfDecl(Type, NameLoc);
@@ -962,12 +963,9 @@ void Sema::ExitDeclaratorContext(Scope *S) {
void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) {
- FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
- if (FunctionTemplateDecl *TFD = dyn_cast_or_null<FunctionTemplateDecl>(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<FunctionTemplateDecl>(OldD))
- Old = OldFunctionTemplate->getTemplatedDecl();
- else
- Old = dyn_cast<FunctionDecl>(OldD);
+ FunctionDecl *Old = OldD->getAsFunction();
if (!Old) {
if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) {
if (New->getFriendObjectKind()) {
@@ -7474,10 +7467,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
if (!getLangOpts().CPlusPlus1y && MD && MD->isConstexpr() &&
!MD->isStatic() && !isa<CXXConstructorDecl>(MD) &&
(MD->getTypeQualifiers() & Qualifiers::Const) == 0) {
- CXXMethodDecl *OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl);
- if (FunctionTemplateDecl *OldTD =
- dyn_cast_or_null<FunctionTemplateDecl>(OldDecl))
- OldMD = dyn_cast<CXXMethodDecl>(OldTD->getTemplatedDecl());
+ CXXMethodDecl *OldMD = 0;
+ if (OldDecl)
+ OldMD = dyn_cast<CXXMethodDecl>(OldDecl->getAsFunction());
if (!OldMD || !OldMD->isStatic()) {
const FunctionProtoType *FPT =
MD->getType()->castAs<FunctionProtoType>();
@@ -9699,24 +9691,15 @@ void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
}
bool Sema::canSkipFunctionBody(Decl *D) {
- if (!Consumer.shouldSkipFunctionBody(D))
- return false;
-
- if (isa<ObjCMethodDecl>(D))
- return true;
-
- FunctionDecl *FD = 0;
- if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
- FD = FTD->getTemplatedDecl();
- else
- FD = cast<FunctionDecl>(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<FunctionTemplateDecl>(dcl);
- if (FunTmpl)
- FD = FunTmpl->getTemplatedDecl();
- else
- FD = dyn_cast_or_null<FunctionDecl>(dcl);
+ FunctionDecl *FD = dcl ? dcl->getAsFunction() : 0;
sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
sema::AnalysisBasedWarnings::Policy *ActivePolicy = 0;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 76b9d669d42..3fe6337d502 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/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<FunctionTemplateDecl>(Target))
- FD = cast<FunctionTemplateDecl>(Target)->getTemplatedDecl();
- else
- FD = cast<FunctionDecl>(Target);
-
+ if (FunctionDecl *FD = Target->getAsFunction()) {
NamedDecl *OldDecl = 0;
switch (CheckOverload(0, FD, Previous, OldDecl, /*IsForUsingDecl*/ true)) {
case Ovl_Overload:
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 7b6536973ae..0f5a78b10a1 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/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<FunctionDecl>(Fn);
- if (!FDecl)
- FDecl = cast<FunctionTemplateDecl>(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<UsingShadowDecl>(D))
- D = USD->getTargetDecl();
- if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
- D = FunTmpl->getTemplatedDecl();
- NoteOverloadCandidate(cast<FunctionDecl>(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<FunctionTemplateDecl>(New)) {
- OldFD = cast<FunctionTemplateDecl>(Old)->getTemplatedDecl();
- NewFD = cast<FunctionTemplateDecl>(New)->getTemplatedDecl();
- } else {
- OldFD = cast<FunctionDecl>(Old);
- NewFD = cast<FunctionDecl>(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/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d35bcabfe2..af47cb4bba0 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/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<FunctionTemplateDecl>(OldD)) {
- if (!IsOverload(New, OldT->getTemplatedDecl(), UseMemberUsingDeclRules)) {
- if (UseMemberUsingDeclRules && OldIsUsingDecl) {
- HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
- continue;
- }
-
- Match = *I;
- return Ovl_Match;
- }
- } else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
+ if (FunctionDecl *OldF = OldD->getAsFunction()) {
if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) {
if (UseMemberUsingDeclRules && OldIsUsingDecl) {
HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
continue;
}
- if (!shouldLinkPossiblyHiddenDecl(*I, New))
+ if (!isa<FunctionTemplateDecl>(OldD) &&
+ !shouldLinkPossiblyHiddenDecl(*I, New))
continue;
Match = *I;
OpenPOWER on IntegriCloud