diff options
Diffstat (limited to 'dist')
29 files changed, 2379 insertions, 876 deletions
diff --git a/dist/changes-4.6.0.md b/dist/changes-4.6.0.md new file mode 100644 index 00000000000..ee899662c69 --- /dev/null +++ b/dist/changes-4.6.0.md @@ -0,0 +1,168 @@ +Qt Creator version 4.6 contains bug fixes and new features. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/4.5..v4.6.0 + +General + +* Locator + * Added filter `b` for bookmarks + * Added filter `t` for triggering items from main menu + * Added filter `=` for evaluating JavaScript expressions + (QTCREATORBUG-14380) +* File System View + * Added bread crumbs for file path (QTCREATORBUG-19203) + * Added `Add New`, `Rename`, `Remove File`, `Diff Against Current File` + (QTCREATORBUG-19213, QTCREATORBUG-19209, QTCREATORBUG-19208, + QTCREATORBUG-19211) +* Added restoration of search flags when choosing search term from history + +Editing + +* Added option to display annotations between lines (QTCREATORBUG-19181) +* Added shortcut setting for jumping to document start and end +* Fixed that editor could jump to end of file when editing in a different split + (QTCREATORBUG-19550) +* Fixed order of items in list of recent documents when documents are suspended + (QTCREATORBUG-19758) +* Fixed crash in generic highlighter (QTCREATORBUG-19916) +* Fixed issue with snippet variables on Gnome (QTCREATORBUG-19571) +* Fixed tool tips in binary editor (QTCREATORBUG-17573) + +Help + +* Improved startup performance + +All Projects + +* Added filtering to project kit setup page + +Qbs Projects + +* Added option to add library paths to dependencies (QTCREATORBUG-19274) + +C++ Support + +* Clang Code Model + * Switched to Clang 5.0, adding support for C++17 + * Implemented information tool tips, which improves type information + including resolution of `auto` types (QTCREATORBUG-11259), template arguments + for template types, and the first or `\brief` paragraph of documentation + comments (QTCREATORBUG-4557) + * Integrated Clang-Tidy and Clazy. + Enable checks in Options > C++ > Code Model > Clang Code Model Warnings + * Added separate highlighting for function definitions (QTCREATORBUG-16625) + +QML Support + +* Added inline annotations for issues from code model + +Debugging + +* Split `Expressions` view from `Locals` view (QTCREATORBUG-19167) +* LLDB + * Fixed attaching to core file (QTCREATORBUG-18722) + * Fixed issue when killing LLDB from the outside (QTCREATORBUG-18723) + +Qt Quick Designer + +* Added font and text properties from Qt 5.10 +* Fixed that items blurred when zooming in +* Fixed crash when changing control focus policy (QTCREATORBUG-19563) +* Fixed assert in backend process with Qt 5.9.4 & 5.10.1 and later + (QTCREATORBUG-19729) + +Version Control Systems + +* Git + * Added `Recover Deleted Files` + * Added `Reload` button to `git log` and `git blame` +* Gerrit + * Added support for private and work-in-progress changes for + Gerrit 2.15 and later + +Diff Viewer + +* Added folding for files and chunks +* Fixed issue with repeated stage and unstage operation + +Test Integration + +* Added grouping of test cases (QTCREATORBUG-17979) +* Fixed handling of `qCritical` output (QTCREATORBUG-19795) +* Google Test + * Fixed detection of crashed tests (QTCREATORBUG-19565) + +Model Editor + +* Removed experimental state +* Added support for text alignment +* Added support for multi-line object names +* Added support for dragging items onto model editor from more panes +* Added `Export Selected Elements` +* Added `Flat` visual role +* Added `Add Related Elements` to diagram context menu +* Added wizard for scratch models +* Moved export actions to `File` menu +* Moved zoom actions to editor tool bar +* Fixed issue with selecting items (QTCREATORBUG-18368) + +Platform Specific + +Windows + +* Added support for the [heob](https://github.com/ssbssa/heob/releases) + memory analyzer +* Fixed detection of CDB in non-default installation roots +* Fixed issue with setting `PATH` versus `Path` environment variable + +Android + +* Fixed issues with GCC include directories in Clang code model + +Remote Linux + +* Fixed that remote application was not killed before deployment + (QTCREATORBUG-19326) + +Credits for these changes go to: +Adam Treat +Alessandro Portale +Alexandru Croitor +Andre Hartmann +André Pönitz +Christian Gagneraud +Christian Kandeler +Christian Stenger +Daniel Engelke +David Schulz +Eike Ziller +Friedemann Kleint +Hannes Domani +Hugo Holgersson +Ivan Donchevskii +Jake Petroules +Jaroslaw Kobus +Jochen Becher +Jörg Bornemann +Marco Benelli +Marco Bubke +Mitch Curtis +Nikita Baryshnikov +Nikolai Kosjar +Oliver Wolff +Orgad Shaneh +Oswald Buddenhagen +Przemyslaw Gorszkowski +Robert Löhning +Thomas Hartmann +Tim Jenssen +Tobias Hunger +Tomasz Olszak +Tor Arne Vestbø +Ulf Hermann +Vikas Pachdha diff --git a/dist/clang/patches/010_D35355_Fix-templated-type-alias-completion-when-using-global-completion-cache.patch b/dist/clang/patches/010_D35355_Fix-templated-type-alias-completion-when-using-global-completion-cache.patch new file mode 100644 index 00000000000..df57bedff83 --- /dev/null +++ b/dist/clang/patches/010_D35355_Fix-templated-type-alias-completion-when-using-global-completion-cache.patch @@ -0,0 +1,71 @@ +diff --git a/tools/clang/lib/Frontend/ASTUnit.cpp b/tools/clang/lib/Frontend/ASTUnit.cpp +index 1094e6d089..5a4cddbebe 100644 +--- a/tools/clang/lib/Frontend/ASTUnit.cpp ++++ b/tools/clang/lib/Frontend/ASTUnit.cpp +@@ -243,7 +243,8 @@ static unsigned getDeclShowContexts(const NamedDecl *ND, + + uint64_t Contexts = 0; + if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || +- isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { ++ isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) || ++ isa<TypeAliasTemplateDecl>(ND)) { + // Types can appear in these contexts. + if (LangOpts.CPlusPlus || !isa<TagDecl>(ND)) + Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel) +diff --git a/tools/clang/lib/Parse/ParseTemplate.cpp b/tools/clang/lib/Parse/ParseTemplate.cpp +index 944cd775d5..6aba10e5c7 100644 +--- a/tools/clang/lib/Parse/ParseTemplate.cpp ++++ b/tools/clang/lib/Parse/ParseTemplate.cpp +@@ -198,9 +198,11 @@ Parser::ParseSingleDeclarationAfterTemplate( + + if (Tok.is(tok::kw_using)) { + // FIXME: We should return the DeclGroup to the caller. +- ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, +- prefixAttrs); +- return nullptr; ++ auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, ++ prefixAttrs); ++ if (!usingDeclPtr || !usingDeclPtr.get().isSingleDecl()) ++ return nullptr; ++ return usingDeclPtr.get().getSingleDecl(); + } + + // Parse the declaration specifiers, stealing any diagnostics from +@@ -1023,8 +1025,8 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, + ? OO_None + : TemplateName.OperatorFunctionId.Operator; + +- TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create( +- SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK, ++ TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create( ++ SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK, + LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds); + + Tok.setAnnotationValue(TemplateId); +diff --git a/tools/clang/test/Index/code-completion.cpp b/tools/clang/test/Index/code-completion.cpp +index f52bb10a35..00f158f3d0 100644 +--- a/tools/clang/test/Index/code-completion.cpp ++++ b/tools/clang/test/Index/code-completion.cpp +@@ -37,6 +37,16 @@ Z::operator int() const { + return 0; + } + ++template <typename T> ++struct Foo { T member; }; ++ ++template<typename T> using Bar = Foo<T>; ++ ++void test_template_alias() { ++ // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s ++ ++} ++ + // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member} + // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member} + // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member} +@@ -88,3 +98,5 @@ Z::operator int() const { + // CHECK-EXPR-NEXT: Class name + // CHECK-EXPR-NEXT: Nested name specifier + // CHECK-EXPR-NEXT: Objective-C interface ++ ++// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50) diff --git a/dist/clang/patches/020_D37435_Dont-show-deleted-function-constructor-candidates-for-code-completion.patch b/dist/clang/patches/020_D37435_Dont-show-deleted-function-constructor-candidates-for-code-completion.patch new file mode 100644 index 00000000000..01a79b27dbf --- /dev/null +++ b/dist/clang/patches/020_D37435_Dont-show-deleted-function-constructor-candidates-for-code-completion.patch @@ -0,0 +1,50 @@ +diff --git a/tools/clang/lib/Sema/SemaCodeComplete.cpp b/tools/clang/lib/Sema/SemaCodeComplete.cpp +index 4de7d42207..7001849426 100644 +--- a/tools/clang/lib/Sema/SemaCodeComplete.cpp ++++ b/tools/clang/lib/Sema/SemaCodeComplete.cpp +@@ -4286,9 +4286,12 @@ static void mergeCandidatesWithResults(Sema &SemaRef, + }); + + // Add the remaining viable overload candidates as code-completion results. +- for (auto &Candidate : CandidateSet) ++ for (auto &Candidate : CandidateSet) { ++ if (Candidate.Function && Candidate.Function->isDeleted()) ++ continue; + if (Candidate.Viable) + Results.push_back(ResultCandidate(Candidate.Function)); ++ } + } + } + +diff --git a/tools/clang/test/Index/complete-constructor-params.cpp b/tools/clang/test/Index/complete-constructor-params.cpp +index 6685626a58..949077a214 100644 +--- a/tools/clang/test/Index/complete-constructor-params.cpp ++++ b/tools/clang/test/Index/complete-constructor-params.cpp +@@ -18,6 +18,20 @@ int main() { + int(42); + } + ++struct Foo { ++ Foo() = default; ++ Foo(const Foo&) = delete; ++}; ++ ++struct Bar { ++ Foo f; ++}; ++ ++void function() { ++ Bar b1; ++ Bar b2(b1); ++} ++ + // RUN: c-index-test -code-completion-at=%s:11:10 %s | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: OverloadCandidate:{Text S}{LeftParen (}{CurrentParameter const S<int> &}{RightParen )} (1) + // CHECK-CC1: OverloadCandidate:{Text S}{LeftParen (}{CurrentParameter int}{Comma , }{Placeholder U}{Comma , }{Placeholder U}{RightParen )} (1) +@@ -138,3 +152,6 @@ int main() { + // CHECK-CC10-NEXT: Class name + // CHECK-CC10-NEXT: Nested name specifier + // CHECK-CC10-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:32:12 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC11 %s ++// CHECK-CC11-NOT: OverloadCandidate:{Text Bar}{LeftParen (}{CurrentParameter const Bar &}{RightParen )} (1) diff --git a/dist/clang/patches/030_D38615_Only-mark-CXCursors-for-explicit-attributes-with-a-type.patch b/dist/clang/patches/030_D38615_Only-mark-CXCursors-for-explicit-attributes-with-a-type.patch new file mode 100644 index 00000000000..3357f874aa7 --- /dev/null +++ b/dist/clang/patches/030_D38615_Only-mark-CXCursors-for-explicit-attributes-with-a-type.patch @@ -0,0 +1,34 @@ +--- /dev/null ++++ b/tools/clang/test/Index/annotate-tokens-unexposed.cpp +@@ -0,0 +1,20 @@ ++// RUN: c-index-test -test-annotate-tokens=%s:1:1:16:1 %s -target x86_64-pc-windows-msvc | FileCheck %s ++class Foo ++{ ++public: ++ void step(int v); ++ Foo(); ++}; ++ ++void bar() ++{ ++ // Introduce a MSInheritanceAttr node on the CXXRecordDecl for Foo. The ++ // existence of this attribute should not mark all cursors for tokens in ++ // Foo as UnexposedAttr. ++ &Foo::step; ++} ++ ++Foo::Foo() ++{} ++ ++// CHECK-NOT: UnexposedAttr= +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -1772,7 +1772,7 @@ + + bool CursorVisitor::VisitAttributes(Decl *D) { + for (const auto *I : D->attrs()) +- if (Visit(MakeCXCursor(I, D, TU))) ++ if (!I->isImplicit() && Visit(MakeCXCursor(I, D, TU))) + return true; + + return false; diff --git a/dist/clang/patches/040_D39957_Honor-TerseOutput-for-constructors.patch b/dist/clang/patches/040_D39957_Honor-TerseOutput-for-constructors.patch new file mode 100644 index 00000000000..a2d096cf16e --- /dev/null +++ b/dist/clang/patches/040_D39957_Honor-TerseOutput-for-constructors.patch @@ -0,0 +1,266 @@ +--- a/tools/clang/lib/AST/DeclPrinter.cpp ++++ b/tools/clang/lib/AST/DeclPrinter.cpp +@@ -608,66 +608,69 @@ + } + + if (CDecl) { +- bool HasInitializerList = false; +- for (const auto *BMInitializer : CDecl->inits()) { +- if (BMInitializer->isInClassMemberInitializer()) +- continue; +- +- if (!HasInitializerList) { +- Proto += " : "; +- Out << Proto; +- Proto.clear(); +- HasInitializerList = true; +- } else +- Out << ", "; ++ if (!Policy.TerseOutput) { ++ bool HasInitializerList = false; ++ for (const auto *BMInitializer : CDecl->inits()) { ++ if (BMInitializer->isInClassMemberInitializer()) ++ continue; + +- if (BMInitializer->isAnyMemberInitializer()) { +- FieldDecl *FD = BMInitializer->getAnyMember(); +- Out << *FD; +- } else { +- Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy); +- } +- +- Out << "("; +- if (!BMInitializer->getInit()) { +- // Nothing to print +- } else { +- Expr *Init = BMInitializer->getInit(); +- if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init)) +- Init = Tmp->getSubExpr(); +- +- Init = Init->IgnoreParens(); +- +- Expr *SimpleInit = nullptr; +- Expr **Args = nullptr; +- unsigned NumArgs = 0; +- if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { +- Args = ParenList->getExprs(); +- NumArgs = ParenList->getNumExprs(); +- } else if (CXXConstructExpr *Construct +- = dyn_cast<CXXConstructExpr>(Init)) { +- Args = Construct->getArgs(); +- NumArgs = Construct->getNumArgs(); ++ if (!HasInitializerList) { ++ Proto += " : "; ++ Out << Proto; ++ Proto.clear(); ++ HasInitializerList = true; + } else +- SimpleInit = Init; +- +- if (SimpleInit) +- SimpleInit->printPretty(Out, nullptr, Policy, Indentation); +- else { +- for (unsigned I = 0; I != NumArgs; ++I) { +- assert(Args[I] != nullptr && "Expected non-null Expr"); +- if (isa<CXXDefaultArgExpr>(Args[I])) +- break; +- +- if (I) +- Out << ", "; +- Args[I]->printPretty(Out, nullptr, Policy, Indentation); ++ Out << ", "; ++ ++ if (BMInitializer->isAnyMemberInitializer()) { ++ FieldDecl *FD = BMInitializer->getAnyMember(); ++ Out << *FD; ++ } else { ++ Out << QualType(BMInitializer->getBaseClass(), 0) ++ .getAsString(Policy); ++ } ++ ++ Out << "("; ++ if (!BMInitializer->getInit()) { ++ // Nothing to print ++ } else { ++ Expr *Init = BMInitializer->getInit(); ++ if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init)) ++ Init = Tmp->getSubExpr(); ++ ++ Init = Init->IgnoreParens(); ++ ++ Expr *SimpleInit = nullptr; ++ Expr **Args = nullptr; ++ unsigned NumArgs = 0; ++ if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { ++ Args = ParenList->getExprs(); ++ NumArgs = ParenList->getNumExprs(); ++ } else if (CXXConstructExpr *Construct = ++ dyn_cast<CXXConstructExpr>(Init)) { ++ Args = Construct->getArgs(); ++ NumArgs = Construct->getNumArgs(); ++ } else ++ SimpleInit = Init; ++ ++ if (SimpleInit) ++ SimpleInit->printPretty(Out, nullptr, Policy, Indentation); ++ else { ++ for (unsigned I = 0; I != NumArgs; ++I) { ++ assert(Args[I] != nullptr && "Expected non-null Expr"); ++ if (isa<CXXDefaultArgExpr>(Args[I])) ++ break; ++ ++ if (I) ++ Out << ", "; ++ Args[I]->printPretty(Out, nullptr, Policy, Indentation); ++ } + } + } ++ Out << ")"; ++ if (BMInitializer->isPackExpansion()) ++ Out << "..."; + } +- Out << ")"; +- if (BMInitializer->isPackExpansion()) +- Out << "..."; + } + } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) { + if (FT && FT->hasTrailingReturn()) { +@@ -712,7 +715,7 @@ + if (D->getBody()) + D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation); + } else { +- if (isa<CXXConstructorDecl>(*D)) ++ if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D)) + Out << " {}"; + } + } +--- a/tools/clang/test/Index/comment-cplus-decls.cpp ++++ b/tools/clang/test/Index/comment-cplus-decls.cpp +@@ -46,7 +46,7 @@ + data* reserved; + }; + // CHECK: <Declaration>class Test {}</Declaration> +-// CHECK: <Declaration>Test() : reserved(new Test::data()) {}</Declaration> ++// CHECK: <Declaration>Test()</Declaration> + // CHECK: <Declaration>unsigned int getID() const</Declaration> + // CHECK: <Declaration>~Test(){{( noexcept)?}}</Declaration> + // CHECK: <Declaration>Test::data *reserved</Declaration> +--- a/tools/clang/unittests/AST/DeclPrinterTest.cpp ++++ b/tools/clang/unittests/AST/DeclPrinterTest.cpp +@@ -31,18 +31,25 @@ + + namespace { + +-void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D) { ++using PrintingPolicyModifier = void (*)(PrintingPolicy &policy); ++ ++void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D, ++ PrintingPolicyModifier PolicyModifier) { + PrintingPolicy Policy = Context->getPrintingPolicy(); + Policy.TerseOutput = true; ++ if (PolicyModifier) ++ PolicyModifier(Policy); + D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false); + } + + class PrintMatch : public MatchFinder::MatchCallback { + SmallString<1024> Printed; + unsigned NumFoundDecls; ++ PrintingPolicyModifier PolicyModifier; + + public: +- PrintMatch() : NumFoundDecls(0) {} ++ PrintMatch(PrintingPolicyModifier PolicyModifier) ++ : NumFoundDecls(0), PolicyModifier(PolicyModifier) {} + + void run(const MatchFinder::MatchResult &Result) override { + const Decl *D = Result.Nodes.getNodeAs<Decl>("id"); +@@ -53,7 +60,7 @@ + return; + + llvm::raw_svector_ostream Out(Printed); +- PrintDecl(Out, Result.Context, D); ++ PrintDecl(Out, Result.Context, D, PolicyModifier); + } + + StringRef getPrinted() const { +@@ -65,13 +72,12 @@ + } + }; + +-::testing::AssertionResult PrintedDeclMatches( +- StringRef Code, +- const std::vector<std::string> &Args, +- const DeclarationMatcher &NodeMatch, +- StringRef ExpectedPrinted, +- StringRef FileName) { +- PrintMatch Printer; ++::testing::AssertionResult ++PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args, ++ const DeclarationMatcher &NodeMatch, ++ StringRef ExpectedPrinted, StringRef FileName, ++ PrintingPolicyModifier PolicyModifier = nullptr) { ++ PrintMatch Printer(PolicyModifier); + MatchFinder Finder; + Finder.addMatcher(NodeMatch, &Printer); + std::unique_ptr<FrontendActionFactory> Factory( +@@ -109,16 +115,17 @@ + "input.cc"); + } + +-::testing::AssertionResult PrintedDeclCXX98Matches( +- StringRef Code, +- const DeclarationMatcher &NodeMatch, +- StringRef ExpectedPrinted) { ++::testing::AssertionResult ++PrintedDeclCXX98Matches(StringRef Code, const DeclarationMatcher &NodeMatch, ++ StringRef ExpectedPrinted, ++ PrintingPolicyModifier PolicyModifier = nullptr) { + std::vector<std::string> Args(1, "-std=c++98"); + return PrintedDeclMatches(Code, + Args, + NodeMatch, + ExpectedPrinted, +- "input.cc"); ++ "input.cc", ++ PolicyModifier); + } + + ::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code, +@@ -478,6 +485,27 @@ + "A(const A &a, int = 0)")); + } + ++TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "struct A {" ++ " int m;" ++ " A() : m(2) {}" ++ "};", ++ cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), ++ "A()")); ++} ++ ++TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "struct A {" ++ " int m;" ++ " A() : m(2) {}" ++ "};", ++ cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), ++ "A() : m(2) {\n}\n", ++ [](PrintingPolicy &Policy){ Policy.TerseOutput = false; })); ++} ++ + TEST(DeclPrinter, TestCXXConstructorDecl5) { + ASSERT_TRUE(PrintedDeclCXX11Matches( + "struct A {" +@@ -540,7 +568,7 @@ + " A(T&&... ts) : T(ts)... {}" + "};", + cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), +- "A<T...>(T &&...ts) : T(ts)... {}")); ++ "A<T...>(T &&...ts)")); + } + + TEST(DeclPrinter, TestCXXDestructorDecl1) { diff --git a/dist/clang/patches/050_D40027_Fix-cursors-for-in-class-initializer-of-field-declarations.patch b/dist/clang/patches/050_D40027_Fix-cursors-for-in-class-initializer-of-field-declarations.patch new file mode 100644 index 00000000000..0e11237a5d8 --- /dev/null +++ b/dist/clang/patches/050_D40027_Fix-cursors-for-in-class-initializer-of-field-declarations.patch @@ -0,0 +1,33 @@ +--- a/tools/clang/test/Index/get-cursor.cpp ++++ b/tools/clang/test/Index/get-cursor.cpp +@@ -152,6 +152,11 @@ + void f_dynamic_noexcept() throw(int); + void f_dynamic_noexcept_any() throw(...); + ++enum EnumType { Enumerator }; ++struct Z { ++ EnumType e = Enumerator; ++}; ++ + // RUN: c-index-test -cursor-at=%s:6:4 %s | FileCheck -check-prefix=CHECK-COMPLETION-1 %s + // CHECK-COMPLETION-1: CXXConstructor=X:6:3 + // CHECK-COMPLETION-1-NEXT: Completion string: {TypedText X}{LeftParen (}{Placeholder int}{Comma , }{Placeholder int}{RightParen )} +@@ -275,3 +280,6 @@ + // CHECK-FORRANGE: 141:18 DeclRefExpr=coll:140:20 Extent=[141:18 - 141:22] Spelling=coll ([141:18 - 141:22]) + // CHECK-FORRANGE: 142:11 DeclRefExpr=lv:141:13 Extent=[142:11 - 142:13] Spelling=lv ([142:11 - 142:13]) + ++// RUN: c-index-test -cursor-at=%s:157:18 -std=c++11 %s | FileCheck -check-prefix=CHECK-INCLASSINITIALIZER %s ++// CHECK-INCLASSINITIALIZER: 157:18 DeclRefExpr=Enumerator:155:17 Extent=[157:18 - 157:28] Spelling=Enumerator ([157:18 - 157:28]) ++ +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -877,6 +877,9 @@ + if (Expr *BitWidth = D->getBitWidth()) + return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest)); + ++ if (Expr *Init = D->getInClassInitializer()) ++ return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest)); ++ + return false; + } + diff --git a/dist/clang/patches/060_D40072_Support-querying-whether-a-declaration-is-invalid.patch b/dist/clang/patches/060_D40072_Support-querying-whether-a-declaration-is-invalid.patch new file mode 100644 index 00000000000..992e1c88f4d --- /dev/null +++ b/dist/clang/patches/060_D40072_Support-querying-whether-a-declaration-is-invalid.patch @@ -0,0 +1,154 @@ +diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h +index 3b5ea9fa53..f2397d1b63 100644 +--- a/tools/clang/include/clang-c/Index.h ++++ b/tools/clang/include/clang-c/Index.h +@@ -33,6 +33,7 @@ + */ + #define CINDEX_VERSION_MAJOR 0 + #define CINDEX_VERSION_MINOR 43 ++#define CINDEX_VERSION_HAS_ISINVALIDECL_BACKPORTED + + #define CINDEX_VERSION_ENCODE(major, minor) ( \ + ((major) * 10000) \ +@@ -2616,6 +2617,16 @@ CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor); + */ + CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind); + ++/** ++ * \brief Determine whether the given declaration is invalid. ++ * ++ * A declaration is invalid if it could not be parsed successfully. ++ * ++ * \returns non-zero if the cursor represents a declaration and it is ++ * invalid, otherwise NULL. ++ */ ++CINDEX_LINKAGE unsigned clang_isInvalidDeclaration(CXCursor); ++ + /** + * \brief Determine whether the given cursor kind represents a simple + * reference. +diff --git a/test/Index/opencl-types.cl b/test/Index/opencl-types.cl +index fe0042aa20..d71893a220 100644 +--- a/tools/clang/test/Index/opencl-types.cl ++++ b/tools/clang/test/Index/opencl-types.cl +@@ -16,11 +16,11 @@ void kernel testFloatTypes() { + double4 vectorDouble; + } + +-// CHECK: VarDecl=scalarHalf:11:8 (Definition) [type=half] [typekind=Half] [isPOD=1] ++// CHECK: VarDecl=scalarHalf:11:8 (Definition){{( \(invalid\))?}} [type=half] [typekind=Half] [isPOD=1] + // CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=half4] [typekind=Typedef] [canonicaltype=half __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1] + // CHECK: VarDecl=scalarFloat:13:9 (Definition) [type=float] [typekind=Float] [isPOD=1] + // CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=float4] [typekind=Typedef] [canonicaltype=float __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1] +-// CHECK: VarDecl=scalarDouble:15:10 (Definition) [type=double] [typekind=Double] [isPOD=1] ++// CHECK: VarDecl=scalarDouble:15:10 (Definition){{( \(invalid\))?}} [type=double] [typekind=Double] [isPOD=1] + // CHECK: VarDecl=vectorDouble:16:11 (Definition) [type=double4] [typekind=Typedef] [canonicaltype=double __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1] + + #pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable +@@ -45,10 +45,10 @@ void kernel OCLImage3dROTest(read_only image3d_t scalarOCLImage3dRO); + // CHECK: ParmDecl=scalarOCLImage2dArrayRO:32:61 (Definition) [type=__read_only image2d_array_t] [typekind=OCLImage2dArrayRO] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage2dDepthRO:33:61 (Definition) [type=__read_only image2d_depth_t] [typekind=OCLImage2dDepthRO] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage2dArrayDepthRO:34:72 (Definition) [type=__read_only image2d_array_depth_t] [typekind=OCLImage2dArrayDepthRO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dMSAARO:35:59 (Definition) [type=__read_only image2d_msaa_t] [typekind=OCLImage2dMSAARO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAARO:36:70 (Definition) [type=__read_only image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAARO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dMSAADepthRO:37:70 (Definition) [type=__read_only image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthRO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthRO:38:81 (Definition) [type=__read_only image2d_array_msaa_depth_t] [typekind=OCLImage2dArrayMSAADepthRO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dMSAARO:35:59 (Definition){{( \(invalid\))?}} [type=__read_only image2d_msaa_t] [typekind=OCLImage2dMSAARO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dArrayMSAARO:36:70 (Definition){{( \(invalid\))?}} [type=__read_only image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAARO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dMSAADepthRO:37:70 (Definition){{( \(invalid\))?}} [type=__read_only image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthRO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthRO:38:81 (Definition){{( \(invalid\))?}} [type=__read_only image2d_array_msaa_depth_t] [typekind=OCLImage2dArrayMSAADepthRO] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage3dRO:39:50 (Definition) [type=__read_only image3d_t] [typekind=OCLImage3dRO] [isPOD=1] + + void kernel OCLImage1dWOTest(write_only image1d_t scalarOCLImage1dWO); +@@ -71,11 +71,11 @@ void kernel OCLImage3dWOTest(write_only image3d_t scalarOCLImage3dWO); + // CHECK: ParmDecl=scalarOCLImage2dArrayWO:58:62 (Definition) [type=__write_only image2d_array_t] [typekind=OCLImage2dArrayWO] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage2dDepthWO:59:62 (Definition) [type=__write_only image2d_depth_t] [typekind=OCLImage2dDepthWO] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage2dArrayDepthWO:60:73 (Definition) [type=__write_only image2d_array_depth_t] [typekind=OCLImage2dArrayDepthWO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dMSAAWO:61:60 (Definition) [type=__write_only image2d_msaa_t] [typekind=OCLImage2dMSAAWO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAAWO:62:71 (Definition) [type=__write_only image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAAWO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dMSAADepthWO:63:71 (Definition) [type=__write_only image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthWO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthWO:64:82 (Definition) [type=__write_only image2d_array_msaa_depth_t] [typekind=OCLImage2dArrayMSAADepthWO] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage3dWO:65:51 (Definition) [type=__write_only image3d_t] [typekind=OCLImage3dWO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dMSAAWO:61:60 (Definition){{( \(invalid\))?}} [type=__write_only image2d_msaa_t] [typekind=OCLImage2dMSAAWO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dArrayMSAAWO:62:71 (Definition){{( \(invalid\))?}} [type=__write_only image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAAWO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dMSAADepthWO:63:71 (Definition){{( \(invalid\))?}} [type=__write_only image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthWO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthWO:64:82 (Definition){{( \(invalid\))?}} [type=__write_only image2d_array_msaa_depth_t] [typekind=OCLImage2dArrayMSAADepthWO] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage3dWO:65:51 (Definition){{( \(invalid\))?}} [type=__write_only image3d_t] [typekind=OCLImage3dWO] [isPOD=1] + + void kernel OCLImage1dRWTest(read_write image1d_t scalarOCLImage1dRW); + void kernel OCLImage1dArrayRWTest(read_write image1d_array_t scalarOCLImage1dArrayRW); +@@ -97,10 +97,10 @@ void kernel OCLImage3dRWTest(read_write image3d_t scalarOCLImage3dRW); + // CHECK: ParmDecl=scalarOCLImage2dArrayRW:84:62 (Definition) [type=__read_write image2d_array_t] [typekind=OCLImage2dArrayRW] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage2dDepthRW:85:62 (Definition) [type=__read_write image2d_depth_t] [typekind=OCLImage2dDepthRW] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage2dArrayDepthRW:86:73 (Definition) [type=__read_write image2d_array_depth_t] [typekind=OCLImage2dArrayDepthRW] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dMSAARW:87:60 (Definition) [type=__read_write image2d_msaa_t] [typekind=OCLImage2dMSAARW] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAARW:88:71 (Definition) [type=__read_write image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAARW] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dMSAADepthRW:89:71 (Definition) [type=__read_write image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthRW] [isPOD=1] +-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthRW:90:82 (Definition) [type=__read_write image2d_array_msaa_depth_t] [typekind=OCLImage2dArrayMSAADepthRW] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dMSAARW:87:60 (Definition){{( \(invalid\))?}} [type=__read_write image2d_msaa_t] [typekind=OCLImage2dMSAARW] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dArrayMSAARW:88:71 (Definition){{( \(invalid\))?}} [type=__read_write image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAARW] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dMSAADepthRW:89:71 (Definition){{( \(invalid\))?}} [type=__read_write image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthRW] [isPOD=1] ++// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthRW:90:82 (Definition){{( \(invalid\))?}} [type=__read_write image2d_array_msaa_depth_t] [typekind=OCLImage2dArrayMSAADepthRW] [isPOD=1] + // CHECK: ParmDecl=scalarOCLImage3dRW:91:51 (Definition) [type=__read_write image3d_t] [typekind=OCLImage3dRW] [isPOD=1] + + void kernel intPipeTestRO(read_only pipe int scalarPipe); +diff --git a/test/Index/print-type-size.cpp b/test/Index/print-type-size.cpp +index 45de93f308..1ea5346273 100644 +--- a/tools/clang/test/Index/print-type-size.cpp ++++ b/tools/clang/test/Index/print-type-size.cpp +@@ -4,8 +4,8 @@ + + namespace basic { + +-// CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) [type=void] [typekind=Void] +-// CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) [type=void] [typekind=Void] ++// CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) (invalid) [type=void] [typekind=Void] ++// CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) (invalid) [type=void] [typekind=Void] + void v; + + // CHECK64: VarDecl=v1:[[@LINE+2]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=8] [alignof=8] +diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c +index cf3581e259..759ed449a4 100644 +--- a/tools/clang/tools/c-index-test/c-index-test.c ++++ b/tools/clang/tools/c-index-test/c-index-test.c +@@ -810,6 +810,8 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) { + printf(" (variadic)"); + if (clang_Cursor_isObjCOptional(Cursor)) + printf(" (@optional)"); ++ if (clang_isInvalidDeclaration(Cursor)) ++ printf(" (invalid)"); + + switch (clang_getCursorExceptionSpecificationType(Cursor)) + { +diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp +index 9ba4d5bf30..584de42e7c 100644 +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -5346,6 +5346,15 @@ unsigned clang_isDeclaration(enum CXCursorKind K) { + (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl); + } + ++unsigned clang_isInvalidDeclaration(CXCursor C) { ++ if (clang_isDeclaration(C.kind)) { ++ if (const Decl *D = getCursorDecl(C)) ++ return D->isInvalidDecl(); ++ } ++ ++ return 0; ++} ++ + unsigned clang_isReference(enum CXCursorKind K) { + return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; + } +diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports +index e0d178a529..7192baab6a 100644 +--- a/tools/clang/tools/libclang/libclang.exports ++++ b/tools/clang/tools/libclang/libclang.exports +@@ -286,6 +286,7 @@ clang_isAttribute + clang_isConstQualifiedType + clang_isCursorDefinition + clang_isDeclaration ++clang_isInvalidDeclaration + clang_isExpression + clang_isFileMultipleIncludeGuarded + clang_isFunctionTypeVariadic diff --git a/dist/clang/patches/070_D40561_Fix-cursors-for-functions-with-trailing-return-type.patch b/dist/clang/patches/070_D40561_Fix-cursors-for-functions-with-trailing-return-type.patch new file mode 100644 index 00000000000..22084c5729a --- /dev/null +++ b/dist/clang/patches/070_D40561_Fix-cursors-for-functions-with-trailing-return-type.patch @@ -0,0 +1,79 @@ +--- a/tools/clang/test/Index/annotate-tokens.cpp ++++ b/tools/clang/test/Index/annotate-tokens.cpp +@@ -37,7 +37,9 @@ class C { + ~C(); + }; + +-// RUN: c-index-test -test-annotate-tokens=%s:1:1:38:1 %s -fno-delayed-template-parsing | FileCheck %s ++auto test5(X) -> X; ++ ++// RUN: c-index-test -test-annotate-tokens=%s:1:1:41:1 %s -std=c++14 -fno-delayed-template-parsing | FileCheck %s + // CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition) + // CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition) + // CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition) +@@ -184,6 +186,14 @@ class C { + // CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt= + // CHECK: Punctuation: "~" [37:3 - 37:4] CXXDestructor=~C:37:3 + // CHECK: Identifier: "C" [37:4 - 37:5] CXXDestructor=~C:37:3 ++// CHECK: Keyword: "auto" [40:1 - 40:5] FunctionDecl=test5:40:6 ++// CHECK: Identifier: "test5" [40:6 - 40:11] FunctionDecl=test5:40:6 ++// CHECK: Punctuation: "(" [40:11 - 40:12] FunctionDecl=test5:40:6 ++// CHECK: Identifier: "X" [40:12 - 40:13] TypeRef=struct X:7:8 ++// CHECK: Punctuation: ")" [40:13 - 40:14] FunctionDecl=test5:40:6 ++// CHECK: Punctuation: "->" [40:15 - 40:17] FunctionDecl=test5:40:6 ++// CHECK: Identifier: "X" [40:18 - 40:19] TypeRef=struct X:7:8 ++// CHECK: Punctuation: ";" [40:19 - 40:20] + + // RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 c-index-test -test-annotate-tokens=%s:32:1:32:13 %s | FileCheck %s -check-prefix=CHECK2 + // CHECK2: Keyword: "if" [32:3 - 32:5] IfStmt= +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -783,6 +783,16 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { + return false; + } + ++static bool HasTrailingReturnType(FunctionDecl *ND) { ++ const QualType Ty = ND->getType(); ++ if (const FunctionType *AFT = Ty->getAs<FunctionType>()) { ++ if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) ++ return FT->hasTrailingReturn(); ++ } ++ ++ return false; ++} ++ + /// \brief Compare two base or member initializers based on their source order. + static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X, + CXXCtorInitializer *const *Y) { +@@ -802,14 +812,16 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { + // written. This requires a bit of work. + TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); + FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>(); ++ const bool HasTrailingRT = HasTrailingReturnType(ND); + + // If we have a function declared directly (without the use of a typedef), + // visit just the return type. Otherwise, just visit the function's type + // now. +- if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) || ++ if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT && ++ Visit(FTL.getReturnLoc())) || + (!FTL && Visit(TL))) + return true; +- ++ + // Visit the nested-name-specifier, if present. + if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc()) + if (VisitNestedNameSpecifierLoc(QualifierLoc)) +@@ -825,7 +837,11 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { + // Visit the function parameters, if we have a function type. + if (FTL && VisitFunctionTypeLoc(FTL, true)) + return true; +- ++ ++ // Visit the function's trailing return type. ++ if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc())) ++ return true; ++ + // FIXME: Attributes? + } + diff --git a/dist/clang/patches/080_D40643_Add-function-to-get-the-buffer-for-a-file.patch b/dist/clang/patches/080_D40643_Add-function-to-get-the-buffer-for-a-file.patch new file mode 100644 index 00000000000..998288dfe95 --- /dev/null +++ b/dist/clang/patches/080_D40643_Add-function-to-get-the-buffer-for-a-file.patch @@ -0,0 +1,78 @@ +diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h +index f2397d1b63..0f4ade266c 100644 +--- a/tools/clang/include/clang-c/Index.h ++++ b/tools/clang/include/clang-c/Index.h +@@ -34,6 +34,7 @@ + #define CINDEX_VERSION_MAJOR 0 + #define CINDEX_VERSION_MINOR 43 + #define CINDEX_VERSION_HAS_ISINVALIDECL_BACKPORTED ++#define CINDEX_VERSION_HAS_GETFILECONTENTS_BACKPORTED + + #define CINDEX_VERSION_ENCODE(major, minor) ( \ + ((major) * 10000) \ +@@ -394,6 +395,21 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file); + CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu, + const char *file_name); + ++/** ++ * \brief Retrieve the buffer associated with the given file. ++ * ++ * \param tu the translation unit ++ * ++ * \param file the file for which to retrieve the buffer. ++ * ++ * \param size [out] if non-NULL, will be set to the size of the buffer. ++ * ++ * \returns a pointer to the buffer in memory that holds the contents of ++ * \p file, or a NULL pointer when the file is not loaded. ++ */ ++CINDEX_LINKAGE const char *clang_getFileContents(CXTranslationUnit tu, ++ CXFile file, size_t *size); ++ + /** + * \brief Returns non-zero if the \c file1 and \c file2 point to the same file, + * or they are both NULL. +diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp +index 13599e1910..7902e8a030 100644 +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -4148,6 +4148,27 @@ CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) { + return const_cast<FileEntry *>(FMgr.getFile(file_name)); + } + ++const char *clang_getFileContents(CXTranslationUnit TU, CXFile file, ++ size_t *size) { ++ if (isNotUsableTU(TU)) { ++ LOG_BAD_TU(TU); ++ return nullptr; ++ } ++ ++ const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager(); ++ FileID fid = SM.translateFile(static_cast<FileEntry *>(file)); ++ bool Invalid = true; ++ llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid); ++ if (Invalid) { ++ if (size) ++ *size = 0; ++ return nullptr; ++ } ++ if (size) ++ *size = buf->getBufferSize(); ++ return buf->getBufferStart(); ++} ++ + unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, + CXFile file) { + if (isNotUsableTU(TU)) { +diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports +index 7192baab6a..c788abb881 100644 +--- a/tools/clang/tools/libclang/libclang.exports ++++ b/tools/clang/tools/libclang/libclang.exports +@@ -216,6 +216,7 @@ clang_getExceptionSpecificationType + clang_getFieldDeclBitWidth + clang_getExpansionLocation + clang_getFile ++clang_getFileContents + clang_getFileLocation + clang_getFileName + clang_getFileTime diff --git a/dist/clang/patches/090_D40746_Correctly-handle-line-table-entries-without-filenames-during-AST-serialization.patch b/dist/clang/patches/090_D40746_Correctly-handle-line-table-entries-without-filenames-during-AST-serialization.patch new file mode 100644 index 00000000000..c165c69fe52 --- /dev/null +++ b/dist/clang/patches/090_D40746_Correctly-handle-line-table-entries-without-filenames-during-AST-serialization.patch @@ -0,0 +1,47 @@ +--- a/tools/clang/lib/Serialization/ASTReader.cpp ++++ b/tools/clang/lib/Serialization/ASTReader.cpp +@@ -1220,6 +1220,7 @@ + + // Parse the file names + std::map<int, int> FileIDs; ++ FileIDs[-1] = -1; // For unspecified filenames. + for (unsigned I = 0; Record[Idx]; ++I) { + // Extract the file name + auto Filename = ReadPath(F, Record, Idx); +--- a/tools/clang/lib/Serialization/ASTWriter.cpp ++++ b/tools/clang/lib/Serialization/ASTWriter.cpp +@@ -2363,12 +2363,13 @@ + + // Emit the needed file names. + llvm::DenseMap<int, int> FilenameMap; ++ FilenameMap[-1] = -1; // For unspecified filenames. + for (const auto &L : LineTable) { + if (L.first.ID < 0) + continue; + for (auto &LE : L.second) { + if (FilenameMap.insert(std::make_pair(LE.FilenameID, +- FilenameMap.size())).second) ++ FilenameMap.size() - 1)).second) + AddPath(LineTable.getFilename(LE.FilenameID), Record); + } + } +--- a/tools/clang/test/PCH/line-directive-nofilename.h ++++ b/tools/clang/test/PCH/line-directive-nofilename.h +@@ -0,0 +1,5 @@ ++#line 42 ++int foo; // This should appear as at line-directive-nofilename.h:42 ++ ++#line 100 "foobar.h" ++int bar; // This should appear as at foobar.h:100 +--- a/tools/clang/test/PCH/line-directive-nofilename.c ++++ b/tools/clang/test/PCH/line-directive-nofilename.c +@@ -0,0 +1,9 @@ ++// RUN: %clang_cc1 -emit-pch -o %t %S/line-directive-nofilename.h ++// RUN: not %clang_cc1 -include-pch %t -fsyntax-only %s 2>&1 | FileCheck %s ++ ++// This causes an "error: redefinition" diagnostic. The notes will have the ++// locations of the declarations from the PCH file. ++double foo, bar; ++ ++// CHECK: line-directive-nofilename.h:42:5: note: previous definition is here ++// CHECK: foobar.h:100:5: note: previous definition is here diff --git a/dist/clang/patches/100_D40841_Fix-a-crash-on-C++17-AST-for-non-trivial-construction-into-a-trivial-brace-initialize.patch b/dist/clang/patches/100_D40841_Fix-a-crash-on-C++17-AST-for-non-trivial-construction-into-a-trivial-brace-initialize.patch new file mode 100644 index 00000000000..e759e4a9f53 --- /dev/null +++ b/dist/clang/patches/100_D40841_Fix-a-crash-on-C++17-AST-for-non-trivial-construction-into-a-trivial-brace-initialize.patch @@ -0,0 +1,117 @@ +--- a/tools/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp ++++ b/tools/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +@@ -22,6 +22,7 @@ + //===----------------------------------------------------------------------===// + + #include "ClangSACheckers.h" ++#include "clang/AST/ParentMap.h" + #include "clang/AST/RecursiveASTVisitor.h" + #include "clang/Basic/Builtins.h" + #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +@@ -262,8 +263,19 @@ + if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion()) { + // We just finished a base constructor. Now we can use the subclass's + // type when resolving virtual calls. +- const Decl *D = C.getLocationContext()->getDecl(); +- recordFixedType(Target, cast<CXXConstructorDecl>(D), C); ++ const LocationContext *LCtx = C.getLocationContext(); ++ ++ // FIXME: In C++17 classes with non-virtual bases may be treated as ++ // aggregates, and in such case no top-frame constructor will be called. ++ // Figure out if we need to do anything in this case. ++ // FIXME: Instead of relying on the ParentMap, we should have the ++ // trigger-statement (InitListExpr in this case) available in this ++ // callback, ideally as part of CallEvent. ++ if (dyn_cast_or_null<InitListExpr>( ++ LCtx->getParentMap().getParent(Ctor->getOriginExpr()))) ++ return; ++ ++ recordFixedType(Target, cast<CXXConstructorDecl>(LCtx->getDecl()), C); + } + return; + } +--- a/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp ++++ b/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +@@ -14,6 +14,7 @@ + #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" + #include "clang/AST/DeclCXX.h" + #include "clang/AST/StmtCXX.h" ++#include "clang/AST/ParentMap.h" + #include "clang/Basic/PrettyStackTrace.h" + #include "clang/StaticAnalyzer/Core/CheckerManager.h" + #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" +@@ -267,6 +268,23 @@ + } + // FALLTHROUGH + case CXXConstructExpr::CK_NonVirtualBase: ++ // In C++17, classes with non-virtual bases may be aggregates, so they would ++ // be initialized as aggregates without a constructor call, so we may have ++ // a base class constructed directly into an initializer list without ++ // having the derived-class constructor call on the previous stack frame. ++ // Initializer lists may be nested into more initializer lists that ++ // correspond to surrounding aggregate initializations. ++ // FIXME: For now this code essentially bails out. We need to find the ++ // correct target region and set it. ++ // FIXME: Instead of relying on the ParentMap, we should have the ++ // trigger-statement (InitListExpr in this case) passed down from CFG or ++ // otherwise always available during construction. ++ if (dyn_cast_or_null<InitListExpr>(LCtx->getParentMap().getParent(CE))) { ++ MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); ++ Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); ++ break; ++ } ++ // FALLTHROUGH + case CXXConstructExpr::CK_Delegating: { + const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); + Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, +--- a/tools/clang/test/Analysis/initializer.cpp ++++ a/tools/clang/test/Analysis/initializer.cpp +@@ -1,4 +1,5 @@ + // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s ++// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -verify %s + + void clang_analyzer_eval(bool); + +@@ -224,3 +225,42 @@ + const char(&f)[2]; + }; + } ++ ++namespace CXX17_aggregate_construction { ++struct A { ++ A(); ++}; ++ ++struct B: public A { ++}; ++ ++struct C: public B { ++}; ++ ++struct D: public virtual A { ++}; ++ ++// In C++17, classes B and C are aggregates, so they will be constructed ++// without actually calling their trivial constructor. Used to crash. ++void foo() { ++ B b = {}; // no-crash ++ const B &bl = {}; // no-crash ++ B &&br = {}; // no-crash ++ ++ C c = {}; // no-crash ++ const C &cl = {}; // no-crash ++ C &&cr = {}; // no-crash ++ ++ D d = {}; // no-crash ++ ++#ifdef CPLUSPLUS17 ++ C cd = {{}}; // no-crash ++ const C &cdl = {{}}; // no-crash ++ C &&cdr = {{}}; // no-crash ++ ++ const B &bll = {{}}; // no-crash ++ const B &bcl = C({{}}); // no-crash ++ B &&bcr = C({{}}); // no-crash ++#endif ++} ++} diff --git a/dist/clang/patches/110_D41016_Fix-crash-in-unused-lambda-capture-warning-for-VLAs.patch b/dist/clang/patches/110_D41016_Fix-crash-in-unused-lambda-capture-warning-for-VLAs.patch new file mode 100644 index 00000000000..f9743162ec4 --- /dev/null +++ b/dist/clang/patches/110_D41016_Fix-crash-in-unused-lambda-capture-warning-for-VLAs.patch @@ -0,0 +1,37 @@ +--- a/tools/clang/include/clang/Sema/ScopeInfo.h ++++ b/tools/clang/include/clang/Sema/ScopeInfo.h +@@ -560,6 +560,7 @@ + void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; } + + VarDecl *getVariable() const { ++ assert(isVariableCapture()); + return VarAndNestedAndThis.getPointer(); + } + +--- a/tools/clang/lib/Sema/SemaLambda.cpp ++++ b/tools/clang/lib/Sema/SemaLambda.cpp +@@ -1481,6 +1481,9 @@ + if (CaptureHasSideEffects(From)) + return; + ++ if (From.isVLATypeCapture()) ++ return; ++ + auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture); + if (From.isThisCapture()) + diag << "'this'"; +--- a/tools/clang/test/SemaCXX/warn-unused-lambda-capture.cpp ++++ b/tools/clang/test/SemaCXX/warn-unused-lambda-capture.cpp +@@ -191,3 +191,12 @@ + void test_use_template() { + test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}} + } ++ ++namespace pr35555 { ++int a; ++void b() { ++ int c[a]; ++ auto vla_used = [&c] { return c[0]; }; ++ auto vla_unused = [&c] {}; // expected-warning{{lambda capture 'c' is not used}} ++} ++} // namespace pr35555 diff --git a/dist/clang/patches/120_D41688_Fix-crash-on-code-completion-in-comment-in-included-file.patch b/dist/clang/patches/120_D41688_Fix-crash-on-code-completion-in-comment-in-included-file.patch new file mode 100644 index 00000000000..14fe7447982 --- /dev/null +++ b/dist/clang/patches/120_D41688_Fix-crash-on-code-completion-in-comment-in-included-file.patch @@ -0,0 +1,47 @@ +--- a/tools/clang/lib/Lex/PPCaching.cpp ++++ b/tools/clang/lib/Lex/PPCaching.cpp +@@ -105,8 +105,10 @@ + } + + void Preprocessor::EnterCachingLexMode() { +- if (InCachingLexMode()) ++ if (InCachingLexMode()) { ++ assert(CurLexerKind == CLK_CachingLexer && "Unexpected lexer kind"); + return; ++ } + + PushIncludeMacroStack(); + CurLexerKind = CLK_CachingLexer; +--- a/tools/clang/lib/Lex/PPLexerChange.cpp ++++ b/tools/clang/lib/Lex/PPLexerChange.cpp +@@ -444,6 +444,7 @@ + } + + CurPPLexer = nullptr; ++ recomputeCurLexerKind(); + return true; + } + +--- /dev/null ++++ b/tools/clang/test/CodeCompletion/Inputs/comments.h +@@ -0,0 +1,4 @@ ++// PR32732 ++struct B { ++ // <- code completion ++}; +--- /dev/null ++++ b/tools/clang/test/CodeCompletion/comments.cpp +@@ -0,0 +1,13 @@ ++// Note: the run lines follow their respective tests, since line/column ++// matter in this test. ++ ++#include "comments.h" ++ ++struct A { ++ // <- code completion ++ /* <- code completion */ ++}; ++ ++// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%s:7:6 %s ++// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%s:8:6 %s ++// RUN: %clang_cc1 -I %S/Inputs -fsyntax-only -code-completion-at=%S/Inputs/comments.h:3:6 %s diff --git a/dist/clang/patches/130_QTCREATORBUG-15157_Link-with-clazy_clang.patch b/dist/clang/patches/130_QTCREATORBUG-15157_Link-with-clazy_clang.patch new file mode 100644 index 00000000000..60acd6d9fa6 --- /dev/null +++ b/dist/clang/patches/130_QTCREATORBUG-15157_Link-with-clazy_clang.patch @@ -0,0 +1,25 @@ +diff --git a/tools/clang/tools/libclang/CIndex.cpp b/tools/clang/tools/libclang/CIndex.cpp +index 66b6edc8b1..281ab77c23 100644 +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -8479,4 +8479,8 @@ static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination = + extern volatile int ClangIncludeFixerPluginAnchorSource; + static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination = + ClangIncludeFixerPluginAnchorSource; ++ ++// This anchor is used to force the linker to link the clazy plugin. ++extern volatile int ClazyPluginAnchorSource; ++static int LLVM_ATTRIBUTE_UNUSED ClazyPluginAnchorDestination = ClazyPluginAnchorSource; + #endif +diff --git a/tools/clang/tools/libclang/CMakeLists.txt b/tools/clang/tools/libclang/CMakeLists.txt +index 4440637820..6798d2ee8b 100644 +--- a/tools/clang/tools/libclang/CMakeLists.txt ++++ b/tools/clang/tools/libclang/CMakeLists.txt +@@ -51,6 +51,7 @@ if (TARGET clangTidyPlugin) + add_definitions(-DCLANG_TOOL_EXTRA_BUILD) + list(APPEND LIBS clangTidyPlugin) + list(APPEND LIBS clangIncludeFixerPlugin) ++ list(APPEND LIBS clazyPlugin) + endif () + + find_library(DL_LIBRARY_PATH dl) diff --git a/dist/clang/patches/140_QTCREATORBUG-15157_Link-with-clazy_extra.patch b/dist/clang/patches/140_QTCREATORBUG-15157_Link-with-clazy_extra.patch new file mode 100644 index 00000000000..f481376fbcf --- /dev/null +++ b/dist/clang/patches/140_QTCREATORBUG-15157_Link-with-clazy_extra.patch @@ -0,0 +1,13 @@ +diff --git a/tools/clang/tools/extra/CMakeLists.txt b/tools/clang/tools/extra/CMakeLists.txt +index 760340a6..53f720c4 100644 +--- a/tools/clang/tools/extra/CMakeLists.txt ++++ b/tools/clang/tools/extra/CMakeLists.txt +@@ -5,6 +5,8 @@ if(CLANG_ENABLE_STATIC_ANALYZER) + add_subdirectory(clang-tidy) + add_subdirectory(clang-tidy-vs) + endif() ++set(CLAZY_BUILD_WITH_CLANG 1) ++add_subdirectory(clazy) + + add_subdirectory(change-namespace) + add_subdirectory(clang-query) diff --git a/dist/clang/patches/150_QTCREATORBUG-15157_Link-with-clazy_llvm.patch b/dist/clang/patches/150_QTCREATORBUG-15157_Link-with-clazy_llvm.patch new file mode 100644 index 00000000000..8862c35f5ca --- /dev/null +++ b/dist/clang/patches/150_QTCREATORBUG-15157_Link-with-clazy_llvm.patch @@ -0,0 +1,23 @@ +diff --git a/lib/Transforms/CMakeLists.txt b/lib/Transforms/CMakeLists.txt +index 67bdeb27212..7fcddb15904 100644 +--- a/lib/Transforms/CMakeLists.txt ++++ b/lib/Transforms/CMakeLists.txt +@@ -4,6 +4,5 @@ add_subdirectory(InstCombine) + add_subdirectory(Scalar) + add_subdirectory(IPO) + add_subdirectory(Vectorize) +-add_subdirectory(Hello) + add_subdirectory(ObjCARC) + add_subdirectory(Coroutines) +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 6cf5103bf44..0b9608a2e52 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -35,7 +35,6 @@ endif() + set(LLVM_TEST_DEPENDS + BugpointPasses + FileCheck +- LLVMHello + UnitTests + bugpoint + count diff --git a/dist/clang/patches/QTCREATORBUG-15449_Fix-files-lock-on-Windows.patch b/dist/clang/patches/160_QTCREATORBUG-15449_Fix-files-lock-on-Windows.patch index 0075d3daba1..9a8c6028fd9 100644 --- a/dist/clang/patches/QTCREATORBUG-15449_Fix-files-lock-on-Windows.patch +++ b/dist/clang/patches/160_QTCREATORBUG-15449_Fix-files-lock-on-Windows.patch @@ -1,11 +1,11 @@ diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp -index b935cbf1ae7..3c9a25062f5 100644 +index 85e782b2c04..95f10753d96 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp -@@ -286,6 +286,11 @@ static bool shouldUseMmap(int FD, +@@ -284,6 +284,11 @@ static bool shouldUseMmap(int FD, bool RequiresNullTerminator, int PageSize, - bool IsVolatileSize) { + bool IsVolatile) { +#ifdef _WIN32 + // Do not use mmap on Windows in order to avoid file locking + return false; diff --git a/dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch b/dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch new file mode 100644 index 00000000000..304e80a2ff9 --- /dev/null +++ b/dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch @@ -0,0 +1,144 @@ +From 363747b90f66f097fd45a6cd665adbaf7612188a Mon Sep 17 00:00:00 2001 +From: Nikolai Kosjar <nikolai.kosjar@qt.io> +Date: Mon, 15 Jan 2018 12:51:18 +0100 +Subject: [PATCH 2/3] Backport: [DeclPrinter] Allow printing fully qualified + name of function declaration + +https://reviews.llvm.org/D40013 +--- + include/clang/AST/PrettyPrinter.h | 7 +++++- + lib/AST/DeclPrinter.cpp | 16 ++++++++---- + unittests/AST/DeclPrinterTest.cpp | 51 ++++++++++++++++++++++++++++++++++++--- + 3 files changed, 64 insertions(+), 10 deletions(-) + +diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h +index 274df220e1..edcef0ae24 100644 +--- a/tools/clang/include/clang/AST/PrettyPrinter.h ++++ b/tools/clang/include/clang/AST/PrettyPrinter.h +@@ -50,7 +50,8 @@ struct PrintingPolicy { + UseVoidForZeroParams(!LO.CPlusPlus), + TerseOutput(false), PolishForDeclaration(false), + Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), +- IncludeNewlines(true), MSVCFormatting(false) { } ++ IncludeNewlines(true), MSVCFormatting(false), ++ FullyQualifiedName(false) { } + + /// \brief Adjust this printing policy for cases where it's known that + /// we're printing C++ code (for instance, if AST dumping reaches a +@@ -200,6 +201,10 @@ struct PrintingPolicy { + /// prints anonymous namespaces as `anonymous namespace' and does not insert + /// spaces after template arguments. + bool MSVCFormatting : 1; ++ ++ /// When true, print the fully qualified name of function declarations. ++ /// This is the opposite of SuppressScope and thus overrules it. ++ bool FullyQualifiedName : 1; + }; + + } // end namespace clang +diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp +index 37f08a4985..ea37abe8f6 100644 +--- a/tools/clang/lib/AST/DeclPrinter.cpp ++++ b/tools/clang/lib/AST/DeclPrinter.cpp +@@ -510,13 +510,19 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { + PrintingPolicy SubPolicy(Policy); + SubPolicy.SuppressSpecifiers = false; + std::string Proto; +- if (!Policy.SuppressScope) { +- if (const NestedNameSpecifier *NS = D->getQualifier()) { +- llvm::raw_string_ostream OS(Proto); +- NS->print(OS, Policy); ++ ++ if (Policy.FullyQualifiedName) { ++ Proto += D->getQualifiedNameAsString(); ++ } else { ++ if (!Policy.SuppressScope) { ++ if (const NestedNameSpecifier *NS = D->getQualifier()) { ++ llvm::raw_string_ostream OS(Proto); ++ NS->print(OS, Policy); ++ } + } ++ Proto += D->getNameInfo().getAsString(); + } +- Proto += D->getNameInfo().getAsString(); ++ + if (GuideDecl) + Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString(); + if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) { +diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp +index dc1977d876..4cf8bce20e 100644 +--- a/tools/clang/unittests/AST/DeclPrinterTest.cpp ++++ b/tools/clang/unittests/AST/DeclPrinterTest.cpp +@@ -104,15 +104,17 @@ PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args, + return ::testing::AssertionSuccess(); + } + +-::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code, +- StringRef DeclName, +- StringRef ExpectedPrinted) { ++::testing::AssertionResult ++PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName, ++ StringRef ExpectedPrinted, ++ PrintingPolicyModifier PolicyModifier = nullptr) { + std::vector<std::string> Args(1, "-std=c++98"); + return PrintedDeclMatches(Code, + Args, + namedDecl(hasName(DeclName)).bind("id"), + ExpectedPrinted, +- "input.cc"); ++ "input.cc", ++ PolicyModifier); + } + + ::testing::AssertionResult +@@ -350,6 +352,47 @@ TEST(DeclPrinter, TestFunctionDecl1) { + "void A()")); + } + ++TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "void A();", ++ "A", ++ "void A()", ++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); ++} ++ ++TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "namespace X { void A(); };", ++ "A", ++ "void X::A()", ++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); ++} ++ ++TEST(DeclPrinter, TestMemberFunction_FullyQualifiedName) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "struct X { void A(); };", ++ "A", ++ "void X::A()", ++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); ++} ++ ++TEST(DeclPrinter, TestMemberFunctionInNamespace_FullyQualifiedName) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "namespace Z { struct X { void A(); }; }", ++ "A", ++ "void Z::X::A()", ++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); ++} ++ ++TEST(DeclPrinter, TestMemberFunctionOutside_FullyQualifiedName) { ++ ASSERT_TRUE(PrintedDeclCXX98Matches( ++ "struct X { void A(); };" ++ "void X::A() {}", ++ functionDecl(hasName("A"), isDefinition()).bind("id"), ++ "void X::A()", ++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); ++} ++ + TEST(DeclPrinter, TestFunctionDecl2) { + ASSERT_TRUE(PrintedDeclCXX98Matches( + "void A() {}", +-- +2.15.1 + diff --git a/dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch b/dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch new file mode 100644 index 00000000000..27b2e2a01e4 --- /dev/null +++ b/dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch @@ -0,0 +1,546 @@ +diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h +index 0f4ade266c..f188ec9d8c 100644 +--- a/tools/clang/include/clang-c/Index.h ++++ b/tools/clang/include/clang-c/Index.h +@@ -35,6 +35,7 @@ + #define CINDEX_VERSION_MINOR 43 + #define CINDEX_VERSION_HAS_ISINVALIDECL_BACKPORTED + #define CINDEX_VERSION_HAS_GETFILECONTENTS_BACKPORTED ++#define CINDEX_VERSION_HAS_PRETTYDECL_BACKPORTED + + #define CINDEX_VERSION_ENCODE(major, minor) ( \ + ((major) * 10000) \ +@@ -4066,6 +4067,90 @@ CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor, + unsigned pieceIndex, + unsigned options); + ++/** ++ * \brief Opaque pointer representing a policy that controls pretty printing ++ * for \c clang_getCursorPrettyPrinted. ++ */ ++typedef void *CXPrintingPolicy; ++ ++/** ++ * \brief Properties for the printing policy. ++ * ++ * See \c clang::PrintingPolicy for more information. ++ */ ++enum CXPrintingPolicyProperty { ++ CXPrintingPolicy_Indentation, ++ CXPrintingPolicy_SuppressSpecifiers, ++ CXPrintingPolicy_SuppressTagKeyword, ++ CXPrintingPolicy_IncludeTagDefinition, ++ CXPrintingPolicy_SuppressScope, ++ CXPrintingPolicy_SuppressUnwrittenScope, ++ CXPrintingPolicy_SuppressInitializers, ++ CXPrintingPolicy_ConstantArraySizeAsWritten, ++ CXPrintingPolicy_AnonymousTagLocations, ++ CXPrintingPolicy_SuppressStrongLifetime, ++ CXPrintingPolicy_SuppressLifetimeQualifiers, ++ CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors, ++ CXPrintingPolicy_Bool, ++ CXPrintingPolicy_Restrict, ++ CXPrintingPolicy_Alignof, ++ CXPrintingPolicy_UnderscoreAlignof, ++ CXPrintingPolicy_UseVoidForZeroParams, ++ CXPrintingPolicy_TerseOutput, ++ CXPrintingPolicy_PolishForDeclaration, ++ CXPrintingPolicy_Half, ++ CXPrintingPolicy_MSWChar, ++ CXPrintingPolicy_IncludeNewlines, ++ CXPrintingPolicy_MSVCFormatting, ++ CXPrintingPolicy_ConstantsAsWritten, /* Ops, not yet there in clang 5.0 and we do not need it. */ ++ CXPrintingPolicy_SuppressImplicitBase, /* Ops, not yet there in clang 5.0 and we do not need it. */ ++ CXPrintingPolicy_FullyQualifiedName, ++ ++ CXPrintingPolicy_LastProperty = CXPrintingPolicy_FullyQualifiedName ++}; ++ ++/** ++ * \brief Get a property value for the given printing policy. ++ */ ++CINDEX_LINKAGE unsigned ++clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy, ++ enum CXPrintingPolicyProperty Property); ++ ++/** ++ * \brief Set a property value for the given printing policy. ++ */ ++CINDEX_LINKAGE void ++clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, ++ enum CXPrintingPolicyProperty Property, ++ unsigned Value); ++ ++/** ++ * \brief Retrieve the default policy for the cursor. ++ * ++ * The policy should be released after use with \c ++ * clang_PrintingPolicy_dispose. ++ */ ++CINDEX_LINKAGE CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor); ++ ++/** ++ * \brief Release a printing policy. ++ */ ++CINDEX_LINKAGE void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy); ++ ++/** ++ * \brief Pretty print declarations. ++ * ++ * \param Cursor The cursor representing a declaration. ++ * ++ * \param Policy The policy to control the entities being printed. If ++ * NULL, a default policy is used. ++ * ++ * \returns The pretty printed declaration or the empty string for ++ * other cursors. ++ */ ++CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor, ++ CXPrintingPolicy Policy); ++ + /** + * \brief Retrieve the display name for the entity referenced by this cursor. + * +diff --git a/test/Index/print-display-names.cpp b/test/Index/print-display-names.cpp +index 94fe4665e6..5ba10e43bc 100644 +--- a/tools/clang/test/Index/print-display-names.cpp ++++ b/tools/clang/test/Index/print-display-names.cpp +@@ -12,9 +12,20 @@ void g(ClassTmpl<T, T>); + + template<> void g<int>(ClassTmpl<int, int>); + +-// RUN: c-index-test -test-load-source all-display %s | FileCheck %s +-// CHECK: print-display-names.cpp:2:7: ClassTemplate=ClassTmpl<T, typename>:2:7 +-// CHECK: print-display-names.cpp:6:16: ClassDecl=ClassTmpl<Integer, Integer>:6:16 (Definition) +-// CHECK: print-display-names.cpp:8:6: FunctionDecl=f(ClassTmpl<float, Integer>):8:6 +-// CHECK: print-display-names.cpp:11:6: FunctionTemplate=g(ClassTmpl<T, T>):11:6 +-// CHECK: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6] ++// RUN: c-index-test -test-load-source all-display %s | FileCheck %s --check-prefix=DISPLAY_NAME ++// DISPLAY_NAME: print-display-names.cpp:2:7: ClassTemplate=ClassTmpl<T, typename>:2:7 ++// DISPLAY_NAME: print-display-names.cpp:6:16: ClassDecl=ClassTmpl<Integer, Integer>:6:16 (Definition) ++// DISPLAY_NAME: print-display-names.cpp:8:6: FunctionDecl=f(ClassTmpl<float, Integer>):8:6 ++// DISPLAY_NAME: print-display-names.cpp:11:6: FunctionTemplate=g(ClassTmpl<T, T>):11:6 ++// DISPLAY_NAME: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6] ++ ++// RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY ++// PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename > class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20] ++// PRETTY: print-display-names.cpp:4:13: TypedefDecl=typedef int Integer:4:13 (Definition) Extent=[4:1 - 4:20] ++// PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<int, int> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] Extent=[6:1 - 6:43] ++// PRETTY: print-display-names.cpp:8:6: FunctionDecl=void f(ClassTmpl<float, Integer> p):8:6 Extent=[8:1 - 8:36] ++// PRETTY: print-display-names.cpp:8:34: ParmDecl=ClassTmpl<float, Integer> p:8:34 (Definition) Extent=[8:8 - 8:35] ++// PRETTY: print-display-names.cpp:11:6: FunctionTemplate=template <typename T> void g(ClassTmpl<T, T>):11:6 Extent=[10:1 - 11:24] ++// PRETTY: print-display-names.cpp:11:23: ParmDecl=ClassTmpl<T, T>:11:23 (Definition) Extent=[11:8 - 11:23] ++// PRETTY: print-display-names.cpp:13:17: FunctionDecl=template<> void g<int>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6] [Template arg 0: kind: 1, type: int] Extent=[13:1 - 13:44] ++// PRETTY: print-display-names.cpp:13:43: ParmDecl=ClassTmpl<int, int>:13:43 (Definition) Extent=[13:24 - 13:43] +diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c +index 759ed449a4..ce2f549234 100644 +--- a/tools/clang/tools/c-index-test/c-index-test.c ++++ b/tools/clang/tools/c-index-test/c-index-test.c +@@ -86,6 +86,69 @@ static unsigned getDefaultParsingOptions() { + return options; + } + ++static void ModifyPrintingPolicyAccordingToEnv(CXPrintingPolicy Policy) { ++ struct Mapping { ++ const char *name; ++ enum CXPrintingPolicyProperty property; ++ }; ++ struct Mapping mappings[] = { ++ {"CINDEXTEST_PRINTINGPOLICY_INDENTATION", CXPrintingPolicy_Indentation}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSPECIFIERS", ++ CXPrintingPolicy_SuppressSpecifiers}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSTAGKEYWORD", ++ CXPrintingPolicy_SuppressTagKeyword}, ++ {"CINDEXTEST_PRINTINGPOLICY_INCLUDETAGDEFINITION", ++ CXPrintingPolicy_IncludeTagDefinition}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSCOPE", ++ CXPrintingPolicy_SuppressScope}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSUNWRITTENSCOPE", ++ CXPrintingPolicy_SuppressUnwrittenScope}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSINITIALIZERS", ++ CXPrintingPolicy_SuppressInitializers}, ++ {"CINDEXTEST_PRINTINGPOLICY_CONSTANTARRAYSIZEASWRITTEN", ++ CXPrintingPolicy_ConstantArraySizeAsWritten}, ++ {"CINDEXTEST_PRINTINGPOLICY_ANONYMOUSTAGLOCATIONS", ++ CXPrintingPolicy_AnonymousTagLocations}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSTRONGLIFETIME", ++ CXPrintingPolicy_SuppressStrongLifetime}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSLIFETIMEQUALIFIERS", ++ CXPrintingPolicy_SuppressLifetimeQualifiers}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSTEMPLATEARGSINCXXCONSTRUCTORS", ++ CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors}, ++ {"CINDEXTEST_PRINTINGPOLICY_BOOL", CXPrintingPolicy_Bool}, ++ {"CINDEXTEST_PRINTINGPOLICY_RESTRICT", CXPrintingPolicy_Restrict}, ++ {"CINDEXTEST_PRINTINGPOLICY_ALIGNOF", CXPrintingPolicy_Alignof}, ++ {"CINDEXTEST_PRINTINGPOLICY_UNDERSCOREALIGNOF", ++ CXPrintingPolicy_UnderscoreAlignof}, ++ {"CINDEXTEST_PRINTINGPOLICY_USEVOIDFORZEROPARAMS", ++ CXPrintingPolicy_UseVoidForZeroParams}, ++ {"CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT", CXPrintingPolicy_TerseOutput}, ++ {"CINDEXTEST_PRINTINGPOLICY_POLISHFORDECLARATION", ++ CXPrintingPolicy_PolishForDeclaration}, ++ {"CINDEXTEST_PRINTINGPOLICY_HALF", CXPrintingPolicy_Half}, ++ {"CINDEXTEST_PRINTINGPOLICY_MSWCHAR", CXPrintingPolicy_MSWChar}, ++ {"CINDEXTEST_PRINTINGPOLICY_INCLUDENEWLINES", ++ CXPrintingPolicy_IncludeNewlines}, ++ {"CINDEXTEST_PRINTINGPOLICY_MSVCFORMATTING", ++ CXPrintingPolicy_MSVCFormatting}, ++ {"CINDEXTEST_PRINTINGPOLICY_CONSTANTSASWRITTEN", ++ CXPrintingPolicy_ConstantsAsWritten}, ++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSIMPLICITBASE", ++ CXPrintingPolicy_SuppressImplicitBase}, ++ {"CINDEXTEST_PRINTINGPOLICY_FULLYQUALIFIEDNAME", ++ CXPrintingPolicy_FullyQualifiedName}, ++ }; ++ ++ unsigned i; ++ for (i = 0; i < sizeof(mappings) / sizeof(struct Mapping); i++) { ++ char *value = getenv(mappings[i].name); ++ if (value) { ++ clang_PrintingPolicy_setProperty(Policy, mappings[i].property, ++ (unsigned)strtoul(value, 0L, 10)); ++ } ++ } ++} ++ + /** \brief Returns 0 in case of success, non-zero in case of a failure. */ + static int checkForErrors(CXTranslationUnit TU); + +@@ -356,7 +419,11 @@ static void PrintRange(CXSourceRange R, const char *str) { + PrintExtent(stdout, begin_line, begin_column, end_line, end_column); + } + +-int want_display_name = 0; ++static enum DisplayType { ++ DisplayType_Spelling, ++ DisplayType_DisplayName, ++ DisplayType_Pretty ++} wanted_display_type = DisplayType_Spelling; + + static void printVersion(const char *Prefix, CXVersion Version) { + if (Version.Major < 0) +@@ -656,6 +723,24 @@ static int lineCol_cmp(const void *p1, const void *p2) { + return (int)lhs->col - (int)rhs->col; + } + ++static CXString CursorToText(CXCursor Cursor) { ++ switch (wanted_display_type) { ++ case DisplayType_Spelling: ++ return clang_getCursorSpelling(Cursor); ++ case DisplayType_DisplayName: ++ return clang_getCursorDisplayName(Cursor); ++ case DisplayType_Pretty: ++ default: { ++ CXString text; ++ CXPrintingPolicy Policy = clang_getCursorPrintingPolicy(Cursor); ++ ModifyPrintingPolicyAccordingToEnv(Policy); ++ text = clang_getCursorPrettyPrinted(Cursor, Policy); ++ clang_PrintingPolicy_dispose(Policy); ++ return text; ++ } ++ } ++} ++ + static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) { + CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor); + if (clang_isInvalid(Cursor.kind)) { +@@ -682,8 +767,7 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) { + int I; + + ks = clang_getCursorKindSpelling(Cursor.kind); +- string = want_display_name? clang_getCursorDisplayName(Cursor) +- : clang_getCursorSpelling(Cursor); ++ string = CursorToText(Cursor); + printf("%s=%s", clang_getCString(ks), + clang_getCString(string)); + clang_disposeString(ks); +@@ -1675,7 +1759,12 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, + else if (!strcmp(filter, "all-display") || + !strcmp(filter, "local-display")) { + ck = NULL; +- want_display_name = 1; ++ wanted_display_type = DisplayType_DisplayName; ++ } ++ else if (!strcmp(filter, "all-pretty") || ++ !strcmp(filter, "local-pretty")) { ++ ck = NULL; ++ wanted_display_type = DisplayType_Pretty; + } + else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0; + else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl; +@@ -1742,8 +1831,11 @@ int perform_test_load_source(int argc, const char **argv, + unsigned I; + + Idx = clang_createIndex(/* excludeDeclsFromPCH */ +- (!strcmp(filter, "local") || +- !strcmp(filter, "local-display"))? 1 : 0, ++ (!strcmp(filter, "local") || ++ !strcmp(filter, "local-display") || ++ !strcmp(filter, "local-pretty")) ++ ? 1 ++ : 0, + /* displayDiagnostics=*/1); + + if ((CommentSchemaFile = parse_comments_schema(argc, argv))) { +diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp +index 45ee9803f2..72b14fdb53 100644 +--- a/tools/clang/tools/libclang/CIndex.cpp ++++ b/tools/clang/tools/libclang/CIndex.cpp +@@ -4652,6 +4652,197 @@ CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) { + return cxstring::createSet(Manglings); + } + ++CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) { ++ if (clang_Cursor_isNull(C)) ++ return 0; ++ return new PrintingPolicy(getCursorContext(C).getPrintingPolicy()); ++} ++ ++void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) { ++ if (Policy) ++ delete static_cast<PrintingPolicy *>(Policy); ++} ++ ++unsigned ++clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy, ++ enum CXPrintingPolicyProperty Property) { ++ if (!Policy) ++ return 0; ++ ++ PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy); ++ switch (Property) { ++ case CXPrintingPolicy_Indentation: ++ return P->Indentation; ++ case CXPrintingPolicy_SuppressSpecifiers: ++ return P->SuppressSpecifiers; ++ case CXPrintingPolicy_SuppressTagKeyword: ++ return P->SuppressTagKeyword; ++ case CXPrintingPolicy_IncludeTagDefinition: ++ return P->IncludeTagDefinition; ++ case CXPrintingPolicy_SuppressScope: ++ return P->SuppressScope; ++ case CXPrintingPolicy_SuppressUnwrittenScope: ++ return P->SuppressUnwrittenScope; ++ case CXPrintingPolicy_SuppressInitializers: ++ return P->SuppressInitializers; ++ case CXPrintingPolicy_ConstantArraySizeAsWritten: ++ return P->ConstantArraySizeAsWritten; ++ case CXPrintingPolicy_AnonymousTagLocations: ++ return P->AnonymousTagLocations; ++ case CXPrintingPolicy_SuppressStrongLifetime: ++ return P->SuppressStrongLifetime; ++ case CXPrintingPolicy_SuppressLifetimeQualifiers: ++ return P->SuppressLifetimeQualifiers; ++ case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors: ++ return P->SuppressTemplateArgsInCXXConstructors; ++ case CXPrintingPolicy_Bool: ++ return P->Bool; ++ case CXPrintingPolicy_Restrict: ++ return P->Restrict; ++ case CXPrintingPolicy_Alignof: ++ return P->Alignof; ++ case CXPrintingPolicy_UnderscoreAlignof: ++ return P->UnderscoreAlignof; ++ case CXPrintingPolicy_UseVoidForZeroParams: ++ return P->UseVoidForZeroParams; ++ case CXPrintingPolicy_TerseOutput: ++ return P->TerseOutput; ++ case CXPrintingPolicy_PolishForDeclaration: ++ return P->PolishForDeclaration; ++ case CXPrintingPolicy_Half: ++ return P->Half; ++ case CXPrintingPolicy_MSWChar: ++ return P->MSWChar; ++ case CXPrintingPolicy_IncludeNewlines: ++ return P->IncludeNewlines; ++ case CXPrintingPolicy_MSVCFormatting: ++ return P->MSVCFormatting; ++ case CXPrintingPolicy_ConstantsAsWritten: ++ // Ops, not yet there in clang 5.0 and we do not need it. ++ return 0; ++ case CXPrintingPolicy_SuppressImplicitBase: ++ // Ops, not yet there in clang 5.0 and we do not need it. ++ return 0; ++ case CXPrintingPolicy_FullyQualifiedName: ++ return P->FullyQualifiedName; ++ } ++ ++ assert(false && "Invalid CXPrintingPolicyProperty"); ++ return 0; ++} ++ ++void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, ++ enum CXPrintingPolicyProperty Property, ++ unsigned Value) { ++ if (!Policy) ++ return; ++ ++ PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy); ++ switch (Property) { ++ case CXPrintingPolicy_Indentation: ++ P->Indentation = Value; ++ return; ++ case CXPrintingPolicy_SuppressSpecifiers: ++ P->SuppressSpecifiers = Value; ++ return; ++ case CXPrintingPolicy_SuppressTagKeyword: ++ P->SuppressTagKeyword = Value; ++ return; ++ case CXPrintingPolicy_IncludeTagDefinition: ++ P->IncludeTagDefinition = Value; ++ return; ++ case CXPrintingPolicy_SuppressScope: ++ P->SuppressScope = Value; ++ return; ++ case CXPrintingPolicy_SuppressUnwrittenScope: ++ P->SuppressUnwrittenScope = Value; ++ return; ++ case CXPrintingPolicy_SuppressInitializers: ++ P->SuppressInitializers = Value; ++ return; ++ case CXPrintingPolicy_ConstantArraySizeAsWritten: ++ P->ConstantArraySizeAsWritten = Value; ++ return; ++ case CXPrintingPolicy_AnonymousTagLocations: ++ P->AnonymousTagLocations = Value; ++ return; ++ case CXPrintingPolicy_SuppressStrongLifetime: ++ P->SuppressStrongLifetime = Value; ++ return; ++ case CXPrintingPolicy_SuppressLifetimeQualifiers: ++ P->SuppressLifetimeQualifiers = Value; ++ return; ++ case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors: ++ P->SuppressTemplateArgsInCXXConstructors = Value; ++ return; ++ case CXPrintingPolicy_Bool: ++ P->Bool = Value; ++ return; ++ case CXPrintingPolicy_Restrict: ++ P->Restrict = Value; ++ return; ++ case CXPrintingPolicy_Alignof: ++ P->Alignof = Value; ++ return; ++ case CXPrintingPolicy_UnderscoreAlignof: ++ P->UnderscoreAlignof = Value; ++ return; ++ case CXPrintingPolicy_UseVoidForZeroParams: ++ P->UseVoidForZeroParams = Value; ++ return; ++ case CXPrintingPolicy_TerseOutput: ++ P->TerseOutput = Value; ++ return; ++ case CXPrintingPolicy_PolishForDeclaration: ++ P->PolishForDeclaration = Value; ++ return; ++ case CXPrintingPolicy_Half: ++ P->Half = Value; ++ return; ++ case CXPrintingPolicy_MSWChar: ++ P->MSWChar = Value; ++ return; ++ case CXPrintingPolicy_IncludeNewlines: ++ P->IncludeNewlines = Value; ++ return; ++ case CXPrintingPolicy_MSVCFormatting: ++ P->MSVCFormatting = Value; ++ return; ++ case CXPrintingPolicy_ConstantsAsWritten: ++ // Ops, not yet there in clang 5.0 and we do not need it. ++ return; ++ case CXPrintingPolicy_SuppressImplicitBase: ++ // Ops, not yet there in clang 5.0 and we do not need it. ++ return; ++ case CXPrintingPolicy_FullyQualifiedName: ++ P->FullyQualifiedName = Value; ++ return; ++ } ++ ++ assert(false && "Invalid CXPrintingPolicyProperty"); ++} ++ ++CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) { ++ if (clang_Cursor_isNull(C)) ++ return cxstring::createEmpty(); ++ ++ if (clang_isDeclaration(C.kind)) { ++ const Decl *D = getCursorDecl(C); ++ if (!D) ++ return cxstring::createEmpty(); ++ ++ SmallString<128> Str; ++ llvm::raw_svector_ostream OS(Str); ++ PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy); ++ D->print(OS, UserPolicy ? *UserPolicy ++ : getCursorContext(C).getPrintingPolicy()); ++ ++ return cxstring::createDup(OS.str()); ++ } ++ ++ return cxstring::createEmpty(); ++} ++ + CXString clang_getCursorDisplayName(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return clang_getCursorSpelling(C); +diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports +index c788abb881..ed4773b132 100644 +--- a/tools/clang/tools/libclang/libclang.exports ++++ b/tools/clang/tools/libclang/libclang.exports +@@ -175,6 +175,8 @@ clang_getCursorAvailability + clang_getCursorCompletionString + clang_getCursorDefinition + clang_getCursorDisplayName ++clang_getCursorPrintingPolicy ++clang_getCursorPrettyPrinted + clang_getCursorExtent + clang_getCursorExceptionSpecificationType + clang_getCursorKind +@@ -355,3 +357,6 @@ clang_EvalResult_isUnsignedInt + clang_EvalResult_getAsDouble + clang_EvalResult_getAsStr + clang_EvalResult_dispose ++clang_PrintingPolicy_getProperty ++clang_PrintingPolicy_setProperty ++clang_PrintingPolicy_dispose +diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp +index f2a96d6be6..342fbd5279 100644 +--- a/tools/clang/unittests/libclang/LibclangTest.cpp ++++ b/tools/clang/unittests/libclang/LibclangTest.cpp +@@ -572,3 +572,35 @@ TEST_F(LibclangReparseTest, clang_parseTranslationUnit2FullArgv) { + EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU)); + DisplayDiagnostics(); + } ++ ++class LibclangPrintingPolicyTest : public LibclangParseTest { ++public: ++ CXPrintingPolicy Policy = nullptr; ++ ++ void SetUp() override { ++ LibclangParseTest::SetUp(); ++ std::string File = "file.cpp"; ++ WriteFile(File, "int i;\n"); ++ ClangTU = clang_parseTranslationUnit(Index, File.c_str(), nullptr, 0, ++ nullptr, 0, TUFlags); ++ CXCursor TUCursor = clang_getTranslationUnitCursor(ClangTU); ++ Policy = clang_getCursorPrintingPolicy(TUCursor); ++ } ++ void TearDown() override { ++ clang_PrintingPolicy_dispose(Policy); ++ LibclangParseTest::TearDown(); ++ } ++}; ++ ++TEST_F(LibclangPrintingPolicyTest, SetAndGetProperties) { ++ for (unsigned Value = 0; Value < 2; ++Value) { ++ for (int I = 0; I < CXPrintingPolicy_LastProperty; ++I) { ++ auto Property = static_cast<enum CXPrintingPolicyProperty>(I); ++ if (Property == CXPrintingPolicy_ConstantsAsWritten || Property == CXPrintingPolicy_SuppressImplicitBase) ++ continue; // These are not yet in clang 5.0. ++ ++ clang_PrintingPolicy_setProperty(Policy, Property, Value); ++ EXPECT_EQ(Value, clang_PrintingPolicy_getProperty(Policy, Property)); ++ } ++ } ++} diff --git a/dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch b/dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch new file mode 100644 index 00000000000..316f3afd178 --- /dev/null +++ b/dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch @@ -0,0 +1,148 @@ +--- a/tools/clang/include/clang/Sema/Sema.h ++++ b/tools/clang/include/clang/Sema/Sema.h +@@ -2707,7 +2707,8 @@ + OverloadCandidateSet &CandidateSet, + TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, + bool SuppressUserConversions = false, +- bool PartialOverloading = false); ++ bool PartialOverloading = false, ++ bool FirstArgumentIsBase = false); + void AddMethodCandidate(DeclAccessPair FoundDecl, + QualType ObjectType, + Expr::Classification ObjectClassification, +--- a/tools/clang/lib/Sema/SemaCodeComplete.cpp ++++ b/tools/clang/lib/Sema/SemaCodeComplete.cpp +@@ -4396,9 +4396,11 @@ + ArgExprs.append(Args.begin(), Args.end()); + UnresolvedSet<8> Decls; + Decls.append(UME->decls_begin(), UME->decls_end()); ++ const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase(); + AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs, + /*SuppressUsedConversions=*/false, +- /*PartialOverloading=*/true); ++ /*PartialOverloading=*/true, ++ FirstArgumentIsBase); + } else { + FunctionDecl *FD = nullptr; + if (auto MCE = dyn_cast<MemberExpr>(NakedFn)) +--- a/tools/clang/lib/Sema/SemaOverload.cpp ++++ b/tools/clang/lib/Sema/SemaOverload.cpp +@@ -6343,24 +6343,36 @@ + OverloadCandidateSet& CandidateSet, + TemplateArgumentListInfo *ExplicitTemplateArgs, + bool SuppressUserConversions, +- bool PartialOverloading) { ++ bool PartialOverloading, ++ 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 (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. ++ 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, Args.slice(1), CandidateSet, ++ ObjectClassification, FunctionArgs, CandidateSet, + SuppressUserConversions, PartialOverloading); + } else { +- AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, ++ // 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 { +--- a/tools/clang/test/Index/complete-call.cpp ++++ b/tools/clang/test/Index/complete-call.cpp +@@ -94,6 +94,24 @@ + s.foo_7(42,); + } + ++struct Bar { ++ static void foo_1(); ++ void foo_1(float); ++ static void foo_1(int); ++}; ++ ++void test() { ++ Bar::foo_1(); ++ Bar b; ++ b.foo_1(); ++} ++ ++struct Bar2 : public Bar { ++ Bar2() { ++ Bar::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: +@@ -803,3 +821,46 @@ + // CHECK-CC59-NEXT: Class name + // CHECK-CC59-NEXT: Nested name specifier + // CHECK-CC59-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:104:14 %s | FileCheck -check-prefix=CHECK-CC60 %s ++// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC60: Completion contexts: ++// CHECK-CC60-NEXT: Any type ++// CHECK-CC60-NEXT: Any value ++// CHECK-CC60-NEXT: Enum tag ++// CHECK-CC60-NEXT: Union tag ++// CHECK-CC60-NEXT: Struct tag ++// CHECK-CC60-NEXT: Class name ++// CHECK-CC60-NEXT: Nested name specifier ++// CHECK-CC60-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:106:11 %s | FileCheck -check-prefix=CHECK-CC61 %s ++// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC61: Completion contexts: ++// CHECK-CC61-NEXT: Any type ++// CHECK-CC61-NEXT: Any value ++// CHECK-CC61-NEXT: Enum tag ++// CHECK-CC61-NEXT: Union tag ++// CHECK-CC61-NEXT: Struct tag ++// CHECK-CC61-NEXT: Class name ++// CHECK-CC61-NEXT: Nested name specifier ++// CHECK-CC61-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:111:16 %s | FileCheck -check-prefix=CHECK-CC62 %s ++// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC62: Completion contexts: ++// CHECK-CC62-NEXT: Any type ++// CHECK-CC62-NEXT: Any value ++// CHECK-CC62-NEXT: Enum tag ++// CHECK-CC62-NEXT: Union tag ++// CHECK-CC62-NEXT: Struct tag ++// CHECK-CC62-NEXT: Class name ++// CHECK-CC62-NEXT: Nested name specifier ++// CHECK-CC62-NEXT: Objective-C interface ++ diff --git a/dist/clang/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch b/dist/clang/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch new file mode 100644 index 00000000000..0223c96e784 --- /dev/null +++ b/dist/clang/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) diff --git a/dist/clang/patches/D15994_Allow-for-unfinished-if-blocks-in-preambles.patch b/dist/clang/patches/D15994_Allow-for-unfinished-if-blocks-in-preambles.patch deleted file mode 100644 index 180d52238d3..00000000000 --- a/dist/clang/patches/D15994_Allow-for-unfinished-if-blocks-in-preambles.patch +++ /dev/null @@ -1,417 +0,0 @@ -diff --git a/tools/clang/include/clang/Lex/Preprocessor.h b/tools/clang/include/clang/Lex/Preprocessor.h -index 30cc37f6f8..3d1d9a86e0 100644 ---- a/tools/clang/include/clang/Lex/Preprocessor.h -+++ b/tools/clang/include/clang/Lex/Preprocessor.h -@@ -277,6 +277,44 @@ class Preprocessor : public RefCountedBase<Preprocessor> { - /// This is used when loading a precompiled preamble. - std::pair<int, bool> SkipMainFilePreamble; - -+ class PreambleConditionalStackStore { -+ enum State { -+ Off = 0, -+ Recording = 1, -+ Replaying = 2, -+ }; -+ -+ public: -+ PreambleConditionalStackStore() : ConditionalStackState(Off) {} -+ -+ void startRecording() { ConditionalStackState = Recording; } -+ void startReplaying() { ConditionalStackState = Replaying; } -+ bool isRecording() const { return ConditionalStackState == Recording; } -+ bool isReplaying() const { return ConditionalStackState == Replaying; } -+ -+ ArrayRef<PPConditionalInfo> getStack() const { -+ return ConditionalStack; -+ } -+ -+ void doneReplaying() { -+ ConditionalStack.clear(); -+ ConditionalStackState = Off; -+ } -+ -+ void setStack(ArrayRef<PPConditionalInfo> s) { -+ if (!isRecording() && !isReplaying()) -+ return; -+ ConditionalStack.clear(); -+ ConditionalStack.append(s.begin(), s.end()); -+ } -+ -+ bool hasRecordedPreamble() const { return !ConditionalStack.empty(); } -+ -+ private: -+ SmallVector<PPConditionalInfo, 4> ConditionalStack; -+ State ConditionalStackState; -+ } PreambleConditionalStack; -+ - /// \brief The current top of the stack that we're lexing from if - /// not expanding a macro and we are lexing directly from source code. - /// -@@ -1662,6 +1700,11 @@ public: - /// \brief Return true if we're in the top-level file, not in a \#include. - bool isInPrimaryFile() const; - -+ /// \brief Return true if we're in the main file (specifically, if we are 0 -+ /// (zero) levels deep \#include. This is used by the lexer to determine if -+ /// it needs to generate errors about unterminated \#if directives. -+ bool isInMainFile() const; -+ - /// \brief Handle cases where the \#include name is expanded - /// from a macro as multiple tokens, which need to be glued together. - /// -@@ -1904,6 +1947,27 @@ public: - const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, - SourceLocation MLoc); - -+ bool isRecordingPreamble() const { -+ return PreambleConditionalStack.isRecording(); -+ } -+ -+ bool hasRecordedPreamble() const { -+ return PreambleConditionalStack.hasRecordedPreamble(); -+ } -+ -+ ArrayRef<PPConditionalInfo> getPreambleConditionalStack() const { -+ return PreambleConditionalStack.getStack(); -+ } -+ -+ void setRecordedPreambleConditionalStack(ArrayRef<PPConditionalInfo> s) { -+ PreambleConditionalStack.setStack(s); -+ } -+ -+ void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s) { -+ PreambleConditionalStack.startReplaying(); -+ PreambleConditionalStack.setStack(s); -+ } -+ - private: - // Macro handling. - void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); -diff --git a/tools/clang/include/clang/Lex/PreprocessorLexer.h b/tools/clang/include/clang/Lex/PreprocessorLexer.h -index 6d6cf05a96..5c2e4d4145 100644 ---- a/tools/clang/include/clang/Lex/PreprocessorLexer.h -+++ b/tools/clang/include/clang/Lex/PreprocessorLexer.h -@@ -17,6 +17,7 @@ - - #include "clang/Lex/MultipleIncludeOpt.h" - #include "clang/Lex/Token.h" -+#include "llvm/ADT/ArrayRef.h" - #include "llvm/ADT/SmallVector.h" - - namespace clang { -@@ -176,6 +177,11 @@ public: - conditional_iterator conditional_end() const { - return ConditionalStack.end(); - } -+ -+ void setConditionalLevels(ArrayRef<PPConditionalInfo> CL) { -+ ConditionalStack.clear(); -+ ConditionalStack.append(CL.begin(), CL.end()); -+ } - }; - - } // end namespace clang -diff --git a/tools/clang/include/clang/Lex/PreprocessorOptions.h b/tools/clang/include/clang/Lex/PreprocessorOptions.h -index 963d95d7f1..47673aa730 100644 ---- a/tools/clang/include/clang/Lex/PreprocessorOptions.h -+++ b/tools/clang/include/clang/Lex/PreprocessorOptions.h -@@ -81,7 +81,14 @@ public: - /// The boolean indicates whether the preamble ends at the start of a new - /// line. - std::pair<unsigned, bool> PrecompiledPreambleBytes; -- -+ -+ /// \brief True indicates that a preamble is being generated. -+ /// -+ /// When the lexer is done, one of the things that need to be preserved is the -+ /// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when -+ /// processing the rest of the file. -+ bool GeneratePreamble; -+ - /// The implicit PTH input included at the start of the translation unit, or - /// empty. - std::string ImplicitPTHInclude; -@@ -145,6 +152,7 @@ public: - AllowPCHWithCompilerErrors(false), - DumpDeserializedPCHDecls(false), - PrecompiledPreambleBytes(0, true), -+ GeneratePreamble(false), - RemappedFilesKeepOriginalName(true), - RetainRemappedFileBuffers(false), - ObjCXXARCStandardLibrary(ARCXX_nolib) { } -diff --git a/tools/clang/include/clang/Serialization/ASTBitCodes.h b/tools/clang/include/clang/Serialization/ASTBitCodes.h -index 79c6a06222..40c63a4ce5 100644 ---- a/tools/clang/include/clang/Serialization/ASTBitCodes.h -+++ b/tools/clang/include/clang/Serialization/ASTBitCodes.h -@@ -580,7 +580,10 @@ namespace clang { - MSSTRUCT_PRAGMA_OPTIONS = 55, - - /// \brief Record code for \#pragma ms_struct options. -- POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56 -+ POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56, -+ -+ /// \brief The stack of open #ifs/#ifdefs recorded in a preamble. -+ PP_CONDITIONAL_STACK = 57, - }; - - /// \brief Record types used within a source manager block. -diff --git a/tools/clang/lib/Frontend/ASTUnit.cpp b/tools/clang/lib/Frontend/ASTUnit.cpp -index c1c2680dcd..b446b53fa4 100644 ---- a/tools/clang/lib/Frontend/ASTUnit.cpp -+++ b/tools/clang/lib/Frontend/ASTUnit.cpp -@@ -1975,6 +1975,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( - PreprocessorOptions &PPOpts = CI->getPreprocessorOpts(); - PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName; - PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors; -+ PPOpts.GeneratePreamble = PrecompilePreambleAfterNParses != 0; - - // Override the resources path. - CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; -diff --git a/tools/clang/lib/Lex/Lexer.cpp b/tools/clang/lib/Lex/Lexer.cpp -index 9c2a0163ac..72f7011d4f 100644 ---- a/tools/clang/lib/Lex/Lexer.cpp -+++ b/tools/clang/lib/Lex/Lexer.cpp -@@ -528,8 +528,6 @@ SourceLocation Lexer::GetBeginningOfToken(SourceLocation Loc, - namespace { - enum PreambleDirectiveKind { - PDK_Skipped, -- PDK_StartIf, -- PDK_EndIf, - PDK_Unknown - }; - } -@@ -551,8 +549,6 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, - - bool InPreprocessorDirective = false; - Token TheTok; -- Token IfStartTok; -- unsigned IfCount = 0; - SourceLocation ActiveCommentLoc; - - unsigned MaxLineOffset = 0; -@@ -635,33 +631,18 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, - .Case("sccs", PDK_Skipped) - .Case("assert", PDK_Skipped) - .Case("unassert", PDK_Skipped) -- .Case("if", PDK_StartIf) -- .Case("ifdef", PDK_StartIf) -- .Case("ifndef", PDK_StartIf) -+ .Case("if", PDK_Skipped) -+ .Case("ifdef", PDK_Skipped) -+ .Case("ifndef", PDK_Skipped) - .Case("elif", PDK_Skipped) - .Case("else", PDK_Skipped) -- .Case("endif", PDK_EndIf) -+ .Case("endif", PDK_Skipped) - .Default(PDK_Unknown); - - switch (PDK) { - case PDK_Skipped: - continue; - -- case PDK_StartIf: -- if (IfCount == 0) -- IfStartTok = HashTok; -- -- ++IfCount; -- continue; -- -- case PDK_EndIf: -- // Mismatched #endif. The preamble ends here. -- if (IfCount == 0) -- break; -- -- --IfCount; -- continue; -- - case PDK_Unknown: - // We don't know what this directive is; stop at the '#'. - break; -@@ -682,16 +663,13 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, - } while (true); - - SourceLocation End; -- if (IfCount) -- End = IfStartTok.getLocation(); -- else if (ActiveCommentLoc.isValid()) -+ if (ActiveCommentLoc.isValid()) - End = ActiveCommentLoc; // don't truncate a decl comment. - else - End = TheTok.getLocation(); - - return std::make_pair(End.getRawEncoding() - StartLoc.getRawEncoding(), -- IfCount? IfStartTok.isAtStartOfLine() -- : TheTok.isAtStartOfLine()); -+ TheTok.isAtStartOfLine()); - } - - -@@ -2528,6 +2506,11 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) { - return true; - } - -+ if (PP->isRecordingPreamble() && !PP->isInMainFile()) { -+ PP->setRecordedPreambleConditionalStack(ConditionalStack); -+ ConditionalStack.clear(); -+ } -+ - // Issue diagnostics for unterminated #if and missing newline. - - // If we are in a #if directive, emit an error. -diff --git a/tools/clang/lib/Lex/PPLexerChange.cpp b/tools/clang/lib/Lex/PPLexerChange.cpp -index e2eceafd98..849a703671 100644 ---- a/tools/clang/lib/Lex/PPLexerChange.cpp -+++ b/tools/clang/lib/Lex/PPLexerChange.cpp -@@ -46,6 +46,12 @@ bool Preprocessor::isInPrimaryFile() const { - return true; - } - -+bool Preprocessor::isInMainFile() const { -+ if (IsFileLexer()) -+ return IncludeMacroStack.size() == 0; -+ return true; -+} -+ - /// getCurrentLexer - Return the current file lexer being lexed from. Note - /// that this ignores any potentially active macro expansions and _Pragma - /// expansions going on at the time. -diff --git a/tools/clang/lib/Lex/Preprocessor.cpp b/tools/clang/lib/Lex/Preprocessor.cpp -index 78179dd798..1da60961a8 100644 ---- a/tools/clang/lib/Lex/Preprocessor.cpp -+++ b/tools/clang/lib/Lex/Preprocessor.cpp -@@ -140,6 +140,9 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, - Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr; - Ident_AbnormalTermination = nullptr; - } -+ -+ if (this->PPOpts->GeneratePreamble) -+ PreambleConditionalStack.startRecording(); - } - - Preprocessor::~Preprocessor() { -@@ -528,6 +531,12 @@ void Preprocessor::EnterMainSourceFile() { - - // Start parsing the predefines. - EnterSourceFile(FID, nullptr, SourceLocation()); -+ -+ // Restore the conditional stack from the preamble, if there is one. -+ if (PreambleConditionalStack.isReplaying()) { -+ CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); -+ PreambleConditionalStack.doneReplaying(); -+ } - } - - void Preprocessor::EndSourceFile() { -diff --git a/tools/clang/lib/Serialization/ASTReader.cpp b/tools/clang/lib/Serialization/ASTReader.cpp -index 9d1554a826..861e867341 100644 ---- a/tools/clang/lib/Serialization/ASTReader.cpp -+++ b/tools/clang/lib/Serialization/ASTReader.cpp -@@ -2799,6 +2799,21 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { - } - break; - -+ case PP_CONDITIONAL_STACK: -+ if (!Record.empty()) { -+ SmallVector<PPConditionalInfo, 4> ConditionalStack; -+ for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) { -+ auto Loc = ReadSourceLocation(F, Record, Idx); -+ bool WasSkipping = Record[Idx++]; -+ bool FoundNonSkip = Record[Idx++]; -+ bool FoundElse = Record[Idx++]; -+ ConditionalStack.push_back( -+ {Loc, WasSkipping, FoundNonSkip, FoundElse}); -+ } -+ PP.setReplayablePreambleConditionalStack(ConditionalStack); -+ } -+ break; -+ - case PP_COUNTER_VALUE: - if (!Record.empty() && Listener) - Listener->ReadCounter(F, Record[0]); -diff --git a/tools/clang/lib/Serialization/ASTWriter.cpp b/tools/clang/lib/Serialization/ASTWriter.cpp -index 7589b0c5dd..dc9bb92dea 100644 ---- a/tools/clang/lib/Serialization/ASTWriter.cpp -+++ b/tools/clang/lib/Serialization/ASTWriter.cpp -@@ -983,6 +983,8 @@ void ASTWriter::WriteBlockInfoBlock() { - RECORD(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS); - RECORD(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES); - RECORD(DELETE_EXPRS_TO_ANALYZE); -+ RECORD(PP_CONDITIONAL_STACK); -+ - - // SourceManager Block. - BLOCK(SOURCE_MANAGER_BLOCK); -@@ -2140,6 +2142,18 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { - Stream.EmitRecord(PP_COUNTER_VALUE, Record); - } - -+ if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) { -+ assert(!IsModule); -+ for (const auto &Cond : PP.getPreambleConditionalStack()) { -+ AddSourceLocation(Cond.IfLoc, Record); -+ Record.push_back(Cond.WasSkipping); -+ Record.push_back(Cond.FoundNonSkip); -+ Record.push_back(Cond.FoundElse); -+ } -+ Stream.EmitRecord(PP_CONDITIONAL_STACK, Record); -+ Record.clear(); -+ } -+ - // Enter the preprocessor block. - Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3); - -diff --git a/tools/clang/test/Lexer/preamble.c b/tools/clang/test/Lexer/preamble.c -index 5b2739abef..762271f2e3 100644 ---- a/tools/clang/test/Lexer/preamble.c -+++ b/tools/clang/test/Lexer/preamble.c -@@ -9,15 +9,12 @@ - #pragma unknown - #endif - #ifdef WIBBLE --#include "honk" --#else --int foo(); -+#include "foo" -+int bar; - #endif - - // This test checks for detection of the preamble of a file, which --// includes all of the starting comments and #includes. Note that any --// changes to the preamble part of this file must be mirrored in --// Inputs/preamble.txt, since we diff against it. -+// includes all of the starting comments and #includes. - - // RUN: %clang_cc1 -print-preamble %s > %t - // RUN: echo END. >> %t -@@ -33,4 +30,6 @@ int foo(); - // CHECK-NEXT: #endif - // CHECK-NEXT: #pragma unknown - // CHECK-NEXT: #endif -+// CHECK-NEXT: #ifdef WIBBLE -+// CHECK-NEXT: #include "foo" - // CHECK-NEXT: END. -diff --git a/tools/clang/test/Lexer/preamble2.c b/tools/clang/test/Lexer/preamble2.c -new file mode 100644 -index 0000000000..499a9a22a5 ---- /dev/null -+++ b/tools/clang/test/Lexer/preamble2.c -@@ -0,0 +1,19 @@ -+// Preamble detection test: header with an include guard. -+#ifndef HEADER_H -+#define HEADER_H -+#include "foo" -+int bar; -+#endif -+ -+// This test checks for detection of the preamble of a file, which -+// includes all of the starting comments and #includes. -+ -+// RUN: %clang_cc1 -print-preamble %s > %t -+// RUN: echo END. >> %t -+// RUN: FileCheck < %t %s -+ -+// CHECK: // Preamble detection test: header with an include guard. -+// CHECK-NEXT: #ifndef HEADER_H -+// CHECK-NEXT: #define HEADER_H -+// CHECK-NEXT: #include "foo" -+// CHECK-NEXT: END. diff --git a/dist/clang/patches/D21176_Mark-invalid-RecordDecls-as-completed.patch b/dist/clang/patches/D21176_Mark-invalid-RecordDecls-as-completed.patch deleted file mode 100644 index a43fc88e99e..00000000000 --- a/dist/clang/patches/D21176_Mark-invalid-RecordDecls-as-completed.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp -index 41719d4e7b..747a4cc0c5 100644 ---- a/tools/clang/lib/Sema/SemaDecl.cpp -+++ b/tools/clang/lib/Sema/SemaDecl.cpp -@@ -13112,7 +13112,14 @@ CreateNewDecl: - OwnedDecl = true; - // In C++, don't return an invalid declaration. We can't recover well from - // the cases where we make the type anonymous. -- return (Invalid && getLangOpts().CPlusPlus) ? nullptr : New; -+ if (Invalid && getLangOpts().CPlusPlus) { -+ if (New->isBeingDefined()) -+ if (auto RD = dyn_cast<RecordDecl>(New)) -+ RD->completeDefinition(); -+ return nullptr; -+ } else { -+ return New; -+ } - } - - void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) { -diff --git a/tools/clang/test/SemaCXX/conversion-function.cpp b/tools/clang/test/SemaCXX/conversion-function.cpp -index 3f494cce8c..c725a0d5b7 100644 ---- a/tools/clang/test/SemaCXX/conversion-function.cpp -+++ b/tools/clang/test/SemaCXX/conversion-function.cpp -@@ -434,8 +434,12 @@ namespace PR18234 { - struct A { - operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}} - operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}} -+ // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const PR18234::A::S &' for 1st argument}} -+#if __cplusplus >= 201103L -+ // expected-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'PR18234::A::S &&' for 1st argument}} -+#endif - } a; -- A::S s = a; -+ A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}} - A::E e = a; // expected-note {{here}} - bool k1 = e == A::e; // expected-error {{no member named 'e'}} - bool k2 = e.n == 0; diff --git a/dist/clang/patches/D27810_FileManager-mark-virtual-file-entries-as-valid-entries.patch b/dist/clang/patches/D27810_FileManager-mark-virtual-file-entries-as-valid-entries.patch deleted file mode 100644 index 009fa0e02ac..00000000000 --- a/dist/clang/patches/D27810_FileManager-mark-virtual-file-entries-as-valid-entries.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/tools/clang/lib/Basic/FileManager.cpp b/tools/clang/lib/Basic/FileManager.cpp -index ce9b7e1bb4..6cfe1f6ebd 100644 ---- a/tools/clang/lib/Basic/FileManager.cpp -+++ b/tools/clang/lib/Basic/FileManager.cpp -@@ -383,6 +383,7 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, - UFE->ModTime = ModificationTime; - UFE->Dir = DirInfo; - UFE->UID = NextFileUID++; -+ UFE->IsValid = true; - UFE->File.reset(); - return UFE; - } diff --git a/dist/clang/patches/D30248_Fix-crash-in-member-access-code-completion-with-implicit-base.patch b/dist/clang/patches/D30248_Fix-crash-in-member-access-code-completion-with-implicit-base.patch deleted file mode 100644 index b8e0afab2e3..00000000000 --- a/dist/clang/patches/D30248_Fix-crash-in-member-access-code-completion-with-implicit-base.patch +++ /dev/null @@ -1,126 +0,0 @@ -diff --git a/tools/clang/lib/Sema/SemaCodeComplete.cpp b/tools/clang/lib/Sema/SemaCodeComplete.cpp -index f4b51a19c2..f4b35fd408 100644 ---- a/tools/clang/lib/Sema/SemaCodeComplete.cpp -+++ b/tools/clang/lib/Sema/SemaCodeComplete.cpp -@@ -4066,7 +4066,10 @@ void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args) { - UME->copyTemplateArgumentsInto(TemplateArgsBuffer); - TemplateArgs = &TemplateArgsBuffer; - } -- SmallVector<Expr *, 12> ArgExprs(1, UME->getBase()); -+ -+ // Add the base as first argument (use a nullptr if the base is implicit). -+ SmallVector<Expr *, 12> ArgExprs( -+ 1, UME->isImplicitAccess() ? nullptr : UME->getBase()); - ArgExprs.append(Args.begin(), Args.end()); - UnresolvedSet<8> Decls; - Decls.append(UME->decls_begin(), UME->decls_end()); -diff --git a/tools/clang/lib/Sema/SemaOverload.cpp b/tools/clang/lib/Sema/SemaOverload.cpp -index 40d6e910f1..19547237ac 100644 ---- a/tools/clang/lib/Sema/SemaOverload.cpp -+++ b/tools/clang/lib/Sema/SemaOverload.cpp -@@ -6051,31 +6051,44 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, - for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { - NamedDecl *D = F.getDecl()->getUnderlyingDecl(); - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { -- if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) -+ if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) { -+ QualType ObjectType; -+ Expr::Classification ObjectClassification; -+ 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. - AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), -- cast<CXXMethodDecl>(FD)->getParent(), -- Args[0]->getType(), Args[0]->Classify(Context), -- Args.slice(1), CandidateSet, -+ cast<CXXMethodDecl>(FD)->getParent(), ObjectType, -+ ObjectClassification, Args.slice(1), CandidateSet, - SuppressUserConversions, PartialOverloading); -- else -+ } else { - AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, - SuppressUserConversions, PartialOverloading); -+ } - } else { - FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D); - if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) && -- !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) -+ !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) { -+ QualType ObjectType; -+ Expr::Classification ObjectClassification; -+ 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. - AddMethodTemplateCandidate(FunTmpl, F.getPair(), -- cast<CXXRecordDecl>(FunTmpl->getDeclContext()), -- ExplicitTemplateArgs, -- Args[0]->getType(), -- Args[0]->Classify(Context), Args.slice(1), -- CandidateSet, SuppressUserConversions, -+ cast<CXXRecordDecl>(FunTmpl->getDeclContext()), -+ ExplicitTemplateArgs, ObjectType, ObjectClassification, -+ Args.slice(1), CandidateSet, SuppressUserConversions, - PartialOverloading); -- else -+ } else { - AddTemplateOverloadCandidate(FunTmpl, F.getPair(), - ExplicitTemplateArgs, Args, - CandidateSet, SuppressUserConversions, - PartialOverloading); -+ } - } - } - } -diff --git a/tools/clang/test/CodeCompletion/member-access.cpp b/tools/clang/test/CodeCompletion/member-access.cpp -index 8f772c0652..8528e18649 100644 ---- a/tools/clang/test/CodeCompletion/member-access.cpp -+++ b/tools/clang/test/CodeCompletion/member-access.cpp -@@ -27,16 +27,31 @@ public: - - void test(const Proxy &p) { - p-> -- // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s -- // CHECK-CC1: Base1 : Base1:: -- // CHECK-CC1: member1 : [#int#][#Base1::#]member1 -- // CHECK-CC1: member1 : [#int#][#Base2::#]member1 -- // CHECK-CC1: member2 : [#float#][#Base1::#]member2 -- // CHECK-CC1: member3 -- // CHECK-CC1: member4 -- // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#float#>) -- // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] -- // CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>) -- // CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>) -- // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>) -- -+} -+ -+struct Foo { -+ void foo() const; -+ static void foo(bool); -+}; -+ -+struct Bar { -+ void foo(bool param) { -+ Foo::foo( );// unresolved member expression with an implicit base -+ } -+}; -+ -+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s -+// CHECK-CC1: Base1 : Base1:: -+// CHECK-CC1: member1 : [#int#][#Base1::#]member1 -+// CHECK-CC1: member1 : [#int#][#Base2::#]member1 -+// CHECK-CC1: member2 : [#float#][#Base1::#]member2 -+// CHECK-CC1: member3 -+// CHECK-CC1: member4 -+// CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#float#>) -+// CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] -+// CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>) -+// CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>) -+// CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>) -+ -+// Make sure this also doesn't crash -+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:39:14 %s diff --git a/dist/clang/patches/D33042_Allow-to-suspend-a-translation-unit.patch b/dist/clang/patches/D33042_Allow-to-suspend-a-translation-unit.patch deleted file mode 100644 index 312db3ace23..00000000000 --- a/dist/clang/patches/D33042_Allow-to-suspend-a-translation-unit.patch +++ /dev/null @@ -1,147 +0,0 @@ -diff --git a/tools/clang/include/clang-c/Index.h b/tools/clang/include/clang-c/Index.h -index 13db2085ba..eb6a5f14b2 100644 ---- a/tools/clang/include/clang-c/Index.h -+++ b/tools/clang/include/clang-c/Index.h -@@ -33,6 +33,7 @@ - */ - #define CINDEX_VERSION_MAJOR 0 - #define CINDEX_VERSION_MINOR 35 -+#define CINDEX_VERSION_HAS_BACKPORTED_SUSPEND - - #define CINDEX_VERSION_ENCODE(major, minor) ( \ - ((major) * 10000) \ -@@ -1404,6 +1405,15 @@ CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU, - unsigned options); - - /** -+ * \brief Suspend a translation unit in order to free memory associated with it. -+ * -+ * A suspended translation unit uses significantly less memory but on the other -+ * side does not support any other calls than \c clang_reparseTranslationUnit -+ * to resume it or \c clang_disposeTranslationUnit to dispose it completely. -+ */ -+CINDEX_LINKAGE unsigned clang_suspendTranslationUnit(CXTranslationUnit); -+ -+/** - * \brief Destroy the specified CXTranslationUnit object. - */ - CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit); -diff --git a/tools/clang/include/clang/Frontend/ASTUnit.h b/tools/clang/include/clang/Frontend/ASTUnit.h -index 3eaf054139..3745ec690e 100644 ---- a/tools/clang/include/clang/Frontend/ASTUnit.h -+++ b/tools/clang/include/clang/Frontend/ASTUnit.h -@@ -870,6 +870,11 @@ public: - bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, - ArrayRef<RemappedFile> RemappedFiles = None); - -+ /// \brief Free data that will be re-generated on the next parse. -+ /// -+ /// Preamble-related data is not affected. -+ void ResetForParse(); -+ - /// \brief Perform code completion at the given file, line, and - /// column within this translation unit. - /// -diff --git a/tools/clang/lib/Frontend/ASTUnit.cpp b/tools/clang/lib/Frontend/ASTUnit.cpp -index b446b53fa4..96437e15bb 100644 ---- a/tools/clang/lib/Frontend/ASTUnit.cpp -+++ b/tools/clang/lib/Frontend/ASTUnit.cpp -@@ -1034,8 +1034,6 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & - /// contain any translation-unit information, false otherwise. - bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, - std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) { -- SavedMainFileBuffer.reset(); -- - if (!Invocation) - return true; - -@@ -1083,16 +1081,12 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, - Clang->createFileManager(); - FileMgr = &Clang->getFileManager(); - } -+ -+ ResetForParse(); -+ - SourceMgr = new SourceManager(getDiagnostics(), *FileMgr, - UserFilesAreVolatile); -- TheSema.reset(); -- Ctx = nullptr; -- PP = nullptr; -- Reader = nullptr; - -- // Clear out old caches and data. -- TopLevelDecls.clear(); -- clearFileLevelDecls(); - CleanTemporaryFiles(); - - if (!OverrideMainBuffer) { -@@ -2082,6 +2076,19 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, - return Result; - } - -+void ASTUnit::ResetForParse() { -+ SavedMainFileBuffer.reset(); -+ -+ SourceMgr.reset(); -+ TheSema.reset(); -+ Ctx.reset(); -+ PP.reset(); -+ Reader.reset(); -+ -+ TopLevelDecls.clear(); -+ clearFileLevelDecls(); -+} -+ - //----------------------------------------------------------------------------// - // Code completion - //----------------------------------------------------------------------------// -diff --git a/tools/clang/tools/c-index-test/c-index-test.c b/tools/clang/tools/c-index-test/c-index-test.c -index 007af9e252..c40bdb888d 100644 ---- a/tools/clang/tools/c-index-test/c-index-test.c -+++ b/tools/clang/tools/c-index-test/c-index-test.c -@@ -1664,6 +1664,8 @@ int perform_test_load_source(int argc, const char **argv, - return -1; - - if (Repeats > 1) { -+ clang_suspendTranslationUnit(TU); -+ - Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, - clang_defaultReparseOptions(TU)); - if (Err != CXError_Success) { -diff --git a/tools/clang/tools/libclang/CIndex.cpp b/tools/clang/tools/libclang/CIndex.cpp -index deb4cc551b..81cb5c3778 100644 ---- a/tools/clang/tools/libclang/CIndex.cpp -+++ b/tools/clang/tools/libclang/CIndex.cpp -@@ -3778,6 +3778,20 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { - } - } - -+unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) { -+ if (CTUnit) { -+ ASTUnit *Unit = cxtu::getASTUnit(CTUnit); -+ -+ if (Unit && Unit->isUnsafeToFree()) -+ return false; -+ -+ Unit->ResetForParse(); -+ return true; -+ } -+ -+ return false; -+} -+ - unsigned clang_defaultReparseOptions(CXTranslationUnit TU) { - return CXReparse_None; - } -diff --git a/tools/clang/tools/libclang/libclang.exports b/tools/clang/tools/libclang/libclang.exports -index c8fe0a21d0..7a8f53d394 100644 ---- a/tools/clang/tools/libclang/libclang.exports -+++ b/tools/clang/tools/libclang/libclang.exports -@@ -298,6 +298,7 @@ clang_remap_getFilenames - clang_remap_getNumFiles - clang_reparseTranslationUnit - clang_saveTranslationUnit -+clang_suspendTranslationUnit - clang_sortCodeCompletionResults - clang_toggleCrashRecovery - clang_tokenize diff --git a/dist/clang/patches/D33493_Cache-source-locations-on-PCH-loading.patch b/dist/clang/patches/D33493_Cache-source-locations-on-PCH-loading.patch deleted file mode 100644 index 7a781ece287..00000000000 --- a/dist/clang/patches/D33493_Cache-source-locations-on-PCH-loading.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff --git a/tools/clang/include/clang/Frontend/ASTUnit.h b/tools/clang/include/clang/Frontend/ASTUnit.h -index 04e6dce511..3eaf054139 100644 ---- a/tools/clang/include/clang/Frontend/ASTUnit.h -+++ b/tools/clang/include/clang/Frontend/ASTUnit.h -@@ -184,6 +184,14 @@ private: - /// some number of calls. - unsigned PreambleRebuildCounter; - -+ /// \brief Cache pairs "filename - source location" -+ /// -+ /// Cache contains only source locations from preamble so it is -+ /// guaranteed that they stay valid when the SourceManager is recreated. -+ /// This cache is used when loading preambule to increase performance -+ /// of that loading. It must be cleared when preamble is recreated. -+ llvm::StringMap<SourceLocation> PreambleSrcLocCache; -+ - public: - class PreambleData { - const FileEntry *File; -diff --git a/tools/clang/lib/Frontend/ASTUnit.cpp b/tools/clang/lib/Frontend/ASTUnit.cpp -index 76fd00a132..c1c2680dcd 100644 ---- a/tools/clang/lib/Frontend/ASTUnit.cpp -+++ b/tools/clang/lib/Frontend/ASTUnit.cpp -@@ -1142,6 +1142,8 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, - if (SavedMainFileBuffer) - TranslateStoredDiagnostics(getFileManager(), getSourceManager(), - PreambleDiagnostics, StoredDiagnostics); -+ else -+ PreambleSrcLocCache.clear(); - - if (!Act->Execute()) - goto error; -@@ -2544,8 +2546,16 @@ void ASTUnit::TranslateStoredDiagnostics( - const FileEntry *FE = FileMgr.getFile(SD.Filename); - if (!FE) - continue; -- FileID FID = SrcMgr.translateFile(FE); -- SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID); -+ SourceLocation FileLoc; -+ auto ItFileID = PreambleSrcLocCache.find(SD.Filename); -+ if (ItFileID == PreambleSrcLocCache.end()) { -+ FileID FID = SrcMgr.translateFile(FE); -+ FileLoc = SrcMgr.getLocForStartOfFile(FID); -+ PreambleSrcLocCache[SD.Filename] = FileLoc; -+ } else { -+ FileLoc = ItFileID->getValue(); -+ } -+ - if (FileLoc.isInvalid()) - continue; - SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset); diff --git a/dist/clang/patches/D34882_Fix-invalid-warnings-for-header-guards-in-preambles.patch b/dist/clang/patches/D34882_Fix-invalid-warnings-for-header-guards-in-preambles.patch deleted file mode 100644 index d7e17fc13ea..00000000000 --- a/dist/clang/patches/D34882_Fix-invalid-warnings-for-header-guards-in-preambles.patch +++ /dev/null @@ -1,82 +0,0 @@ -diff --git a/tools/clang/include/clang/Lex/Preprocessor.h b/tools/clang/include/clang/Lex/Preprocessor.h -index 3d1d9a86e0..0a02c977fc 100644 ---- a/tools/clang/include/clang/Lex/Preprocessor.h -+++ b/tools/clang/include/clang/Lex/Preprocessor.h -@@ -1034,6 +1034,8 @@ public: - /// which implicitly adds the builtin defines etc. - void EnterMainSourceFile(); - -+ void replayPreambleConditionalStack(); -+ - /// \brief Inform the preprocessor callbacks that processing is complete. - void EndSourceFile(); - -@@ -1700,11 +1702,6 @@ public: - /// \brief Return true if we're in the top-level file, not in a \#include. - bool isInPrimaryFile() const; - -- /// \brief Return true if we're in the main file (specifically, if we are 0 -- /// (zero) levels deep \#include. This is used by the lexer to determine if -- /// it needs to generate errors about unterminated \#if directives. -- bool isInMainFile() const; -- - /// \brief Handle cases where the \#include name is expanded - /// from a macro as multiple tokens, which need to be glued together. - /// -diff --git a/tools/clang/lib/Lex/Lexer.cpp b/tools/clang/lib/Lex/Lexer.cpp -index 72f7011d4f..5953412608 100644 ---- a/tools/clang/lib/Lex/Lexer.cpp -+++ b/tools/clang/lib/Lex/Lexer.cpp -@@ -2506,7 +2506,7 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) { - return true; - } - -- if (PP->isRecordingPreamble() && !PP->isInMainFile()) { -+ if (PP->isRecordingPreamble() && PP->isInPrimaryFile()) { - PP->setRecordedPreambleConditionalStack(ConditionalStack); - ConditionalStack.clear(); - } -diff --git a/tools/clang/lib/Lex/PPLexerChange.cpp b/tools/clang/lib/Lex/PPLexerChange.cpp -index 849a703671..e2eceafd98 100644 ---- a/tools/clang/lib/Lex/PPLexerChange.cpp -+++ b/tools/clang/lib/Lex/PPLexerChange.cpp -@@ -46,12 +46,6 @@ bool Preprocessor::isInPrimaryFile() const { - return true; - } - --bool Preprocessor::isInMainFile() const { -- if (IsFileLexer()) -- return IncludeMacroStack.size() == 0; -- return true; --} -- - /// getCurrentLexer - Return the current file lexer being lexed from. Note - /// that this ignores any potentially active macro expansions and _Pragma - /// expansions going on at the time. -diff --git a/tools/clang/lib/Lex/Preprocessor.cpp b/tools/clang/lib/Lex/Preprocessor.cpp -index 1da60961a8..bb67b9c77a 100644 ---- a/tools/clang/lib/Lex/Preprocessor.cpp -+++ b/tools/clang/lib/Lex/Preprocessor.cpp -@@ -531,7 +531,9 @@ void Preprocessor::EnterMainSourceFile() { - - // Start parsing the predefines. - EnterSourceFile(FID, nullptr, SourceLocation()); -+} - -+void Preprocessor::replayPreambleConditionalStack() { - // Restore the conditional stack from the preamble, if there is one. - if (PreambleConditionalStack.isReplaying()) { - CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); -diff --git a/tools/clang/lib/Parse/Parser.cpp b/tools/clang/lib/Parse/Parser.cpp -index f968f995d5..45662e7866 100644 ---- a/tools/clang/lib/Parse/Parser.cpp -+++ b/tools/clang/lib/Parse/Parser.cpp -@@ -528,6 +528,8 @@ void Parser::Initialize() { - - // Prime the lexer look-ahead. - ConsumeToken(); -+ -+ PP.replayPreambleConditionalStack(); - } - - void Parser::LateTemplateParserCleanupCallback(void *P) { diff --git a/dist/clang/patches/README.md b/dist/clang/patches/README.md new file mode 100644 index 00000000000..86e84e74de0 --- /dev/null +++ b/dist/clang/patches/README.md @@ -0,0 +1,131 @@ +Extra patches to LLVM/Clang 5.0 +=============================== + +The patches in this directory are applied to LLVM/Clang with: + + $ cd $LLVM_SOURCE_DIR + $ git apply --whitespace=fix $QT_CREATOR_SOURCE/dist/clang/patches/*.patch + +Backported changes +------------------ + +##### 110_D41016_Fix-crash-in-unused-lambda-capture-warning-for-VLAs.patch + +* <https://reviews.llvm.org/D41016> + +[Sema] Fix crash in unused-lambda-capture warning for VLAs + +##### 010_D35355_Fix-templated-type-alias-completion-when-using-global-completion-cache.patch + +* <https://reviews.llvm.org/D35355> + +Fixes completion involving templated type alias. + +##### 120_D41688_Fix-crash-on-code-completion-in-comment-in-included-file.patch + +* <https://reviews.llvm.org/D41688> + +[Lex] Fix crash on code completion in comment in included file. + +##### 100_D40841_Fix-a-crash-on-C++17-AST-for-non-trivial-construction-into-a-trivial-brace-initialize.patch + +* <https://reviews.llvm.org/D40841> + +[analyzer] Fix a crash on C++17 AST for non-trivial construction into a trivial brace initializer. + +##### 090_D40746_Correctly-handle-line-table-entries-without-filenames-during-AST-serialization.patch + +* <https://reviews.llvm.org/D40746> + +Correctly handle line table entries without filenames during AST serialization +Fixes crash during a reparse. + +##### 050_D40027_Fix-cursors-for-in-class-initializer-of-field-declarations.patch + +* <https://reviews.llvm.org/D40027> +* <https://bugs.llvm.org/show_bug.cgi?id=33745> + +[libclang] Fix cursors for in-class initializer of field declarations +Fixes AST access to initializers of class members. Affects mostly semantic highlighting and highlighting of local uses. + +##### 070_D40561_Fix-cursors-for-functions-with-trailing-return-type.patch + +* <https://reviews.llvm.org/D40561> + +[libclang] Fix cursors for functions with trailing return type + +##### 060_D40072_Support-querying-whether-a-declaration-is-invalid.patch + +* <https://reviews.llvm.org/D40072> + +[libclang] Add support for checking abstractness of records +Would need https://codereview.qt-project.org/#/c/211497/ on Qt Creator side. + +##### 040_D39957_Honor-TerseOutput-for-constructors.patch + +* <https://reviews.llvm.org/D39957> + +[DeclPrinter] Honor TerseOutput for constructors +Avoids printing member initialization list and body for constructor. + +##### 080_D40643_Add-function-to-get-the-buffer-for-a-file.patch + +* <https://reviews.llvm.org/D40643> +* <https://reviews.llvm.org/rL319881> + +[libclang] Add function to get the buffer for a file +Together with https://codereview.qt-project.org/#/c/212972/ fixes highlighting + +##### 030_D38615_Only-mark-CXCursors-for-explicit-attributes-with-a-type.patch + +* <https://reviews.llvm.org/D38615> + +[libclang] Only mark CXCursors for explicit attributes with a type +Some classes have totally broken highlighting (like classes inside texteditor.cpp) + +##### 170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch +##### 180_D39903_libclang-Allow-pretty-printing-declarations.patch + +* <https://reviews.llvm.org/D40013> +* <https://reviews.llvm.org/D39903> + +[DeclPrinter] Allow printing fully qualified name of function declaration +[libclang] Allow pretty printing declarations + +Improves pretty printing for tooltips. + +Additional changes +------------------ + +##### 160_QTCREATORBUG-15449_Fix-files-lock-on-Windows.patch + +* <https://reviews.llvm.org/D35200> +* <https://bugreports.qt.io/browse/QTCREATORBUG-15449> + +Significantly reduces problems when saving a header file on Windows. + +##### 150_QTCREATORBUG-15157_Link-with-clazy_llvm.patch +##### 130_QTCREATORBUG-15157_Link-with-clazy_clang.patch +##### 140_QTCREATORBUG-15157_Link-with-clazy_extra.patch + +* <https://bugreports.qt.io/browse/QTCREATORBUG-15157> + +Builds Clazy as an LLVM part and forces link for Clazy plugin registry entry. + +##### 200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch + +* <https://reviews.llvm.org/D36390> +* <https://bugs.llvm.org/show_bug.cgi?id=33904> + +Fix overloaded static functions in SemaCodeComplete + +Happens when static function is accessed via the class variable. +That leads to incorrect overloads number because the variable is considered as the first argument. + +##### 210_D43453_Fix-overloaded-static-functions-for-templates.patch + +* <https://reviews.llvm.org/D43453> + +Fix overloaded static functions for templates + +Apply almost the same fix as D36390 but for templates |