summaryrefslogtreecommitdiffstats
path: root/development/qt-creator-llvm/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch
diff options
context:
space:
mode:
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.patch165
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)