diff options
Diffstat (limited to 'development/qt-creator-llvm/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch')
-rw-r--r-- | development/qt-creator-llvm/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/development/qt-creator-llvm/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch b/development/qt-creator-llvm/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch new file mode 100644 index 0000000000..0223c96e78 --- /dev/null +++ b/development/qt-creator-llvm/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch @@ -0,0 +1,165 @@ +diff --git a/tools/clang/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp +index 1b07ec60ce..46ed08d1cf 100644 +--- a/tools/clang/lib/Sema/SemaOverload.cpp ++++ b/tools/clang/lib/Sema/SemaOverload.cpp +@@ -6321,57 +6321,56 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, + bool FirstArgumentIsBase) { + for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { + NamedDecl *D = F.getDecl()->getUnderlyingDecl(); +- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { +- ArrayRef<Expr *> FunctionArgs = Args; +- if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) { +- QualType ObjectType; +- Expr::Classification ObjectClassification; +- if (Args.size() > 0) { +- if (Expr *E = Args[0]) { +- // Use the explit base to restrict the lookup: +- ObjectType = E->getType(); +- ObjectClassification = E->Classify(Context); +- } // .. else there is an implit base. +- FunctionArgs = Args.slice(1); +- } +- AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), +- cast<CXXMethodDecl>(FD)->getParent(), ObjectType, +- ObjectClassification, FunctionArgs, CandidateSet, +- SuppressUserConversions, PartialOverloading); +- } else { +- // Slice the first argument (which is the base) when we access +- // static method as non-static +- if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) && +- !isa<CXXConstructorDecl>(FD)))) { +- assert(cast<CXXMethodDecl>(FD)->isStatic()); +- FunctionArgs = Args.slice(1); +- } +- AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, +- SuppressUserConversions, PartialOverloading); +- } +- } else { +- FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D); +- if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) && +- !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) { +- QualType ObjectType; +- Expr::Classification ObjectClassification; ++ ArrayRef<Expr *> FunctionArgs = Args; ++ ++ FunctionTemplateDecl *FunTmpl = nullptr; ++ FunctionDecl *FD = dyn_cast<FunctionDecl>(D); ++ ++ const bool IsTemplate = FD ? false : true; ++ if (IsTemplate) { ++ FunTmpl = cast<FunctionTemplateDecl>(D); ++ FD = FunTmpl->getTemplatedDecl(); ++ } ++ ++ if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) { ++ QualType ObjectType; ++ Expr::Classification ObjectClassification; ++ if (Args.size() > 0) { + if (Expr *E = Args[0]) { + // Use the explit base to restrict the lookup: + ObjectType = E->getType(); + ObjectClassification = E->Classify(Context); + } // .. else there is an implit base. ++ FunctionArgs = Args.slice(1); ++ } ++ if (IsTemplate) + AddMethodTemplateCandidate( + FunTmpl, F.getPair(), + cast<CXXRecordDecl>(FunTmpl->getDeclContext()), + ExplicitTemplateArgs, ObjectType, ObjectClassification, +- Args.slice(1), CandidateSet, SuppressUserConversions, ++ FunctionArgs, CandidateSet, SuppressUserConversions, + PartialOverloading); +- } else { +- AddTemplateOverloadCandidate(FunTmpl, F.getPair(), +- ExplicitTemplateArgs, Args, +- CandidateSet, SuppressUserConversions, +- PartialOverloading); ++ else ++ AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), ++ cast<CXXMethodDecl>(FD)->getParent(), ObjectType, ++ ObjectClassification, FunctionArgs, CandidateSet, ++ SuppressUserConversions, PartialOverloading); ++ } else { ++ // Slice the first argument (which is the base) when we access ++ // static method as non-static ++ if (Args.size() > 0 && ++ (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) && ++ !isa<CXXConstructorDecl>(FD)))) { ++ assert(cast<CXXMethodDecl>(FD)->isStatic()); ++ FunctionArgs = Args.slice(1); + } ++ if (IsTemplate) ++ AddTemplateOverloadCandidate( ++ FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, ++ CandidateSet, SuppressUserConversions, PartialOverloading); ++ else ++ AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, ++ SuppressUserConversions, PartialOverloading); + } + } + } +diff --git a/tools/clang/test/Index/complete-call.cpp b/test/Index/complete-call.cpp +index ca116485ac..35f2009066 100644 +--- a/tools/clang/test/Index/complete-call.cpp ++++ b/tools/clang/test/Index/complete-call.cpp +@@ -112,6 +112,33 @@ struct Bar2 : public Bar { + } + }; + ++struct BarTemplates { ++ static void foo_1() {} ++ void foo_1(float) {} ++ static void foo_1(int) {} ++ ++ template<class T1, class T2> ++ static void foo_1(T1 a, T2 b) { a + b; } ++ ++ template<class T1, class T2> ++ void foo_1(T1 a, T2 b, float c) { a + b + c; } ++ ++ template<class T1, class T2> ++ static void foo_1(T2 a, int b, T1 c) { a + b + c; } ++}; ++ ++void testTemplates() { ++ BarTemplates::foo_1(); ++ BarTemplates b; ++ b.foo_1(); ++} ++ ++struct Bar2Template : public BarTemplates { ++ Bar2Template() { ++ BarTemplates::foo_1(); ++ } ++}; ++ + // RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) + // CHECK-CC1: Completion contexts: +@@ -864,3 +891,25 @@ struct Bar2 : public Bar { + // CHECK-CC62-NEXT: Nested name specifier + // CHECK-CC62-NEXT: Objective-C interface + ++// RUN: c-index-test -code-completion-at=%s:131:23 %s | FileCheck -check-prefix=CHECK-CC63 %s ++// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) ++// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1) ++// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1) ++ ++// RUN: c-index-test -code-completion-at=%s:133:11 %s | FileCheck -check-prefix=CHECK-CC64 %s ++// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) ++// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1) ++ ++// RUN: c-index-test -code-completion-at=%s:138:25 %s | FileCheck -check-prefix=CHECK-CC65 %s ++// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1) ++// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1) ++// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1) |