[PATCH] D38939: [clangd] Handle exit notification (proper shutdown)
sammccall accepted this revision. sammccall added inline comments. This revision is now accepted and ready to land. Comment at: test/clangd/authority-less-uri.test:33 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +Content-Length: 33 Having the shutdown/exit boilerplate in every test seems unfortunate. (I realize this isn't new here, but it's getting worse!) Does clangd exit cleanly on stdin EOF? If it could be made to do so, maybe we could just have e.g. the initialize test do the full sequence, and the other tests omit shutdown. https://reviews.llvm.org/D38939 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38943: [ASTImporter] import SubStmt of CaseStmt
r.stahl created this revision. This fixes importing of CaseStmts, because the importer was not importing its SubStmt. A test was added and the test procedure was adjusted to also dump the imported Decl, because otherwise the bug would not be detected. https://reviews.llvm.org/D38943 Files: lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -97,6 +97,9 @@ llvm::raw_svector_ostream ToNothing(ImportChecker); ToCtx.getTranslationUnitDecl()->print(ToNothing); + // This might catch other cases. + Imported->dump(ToNothing); + return Verifier.match(Imported, AMatcher); } @@ -267,6 +270,15 @@ hasUnaryOperand(cxxThisExpr(); } +TEST(ImportExpr, ImportSwitch) { + MatchVerifier Verifier; + EXPECT_TRUE( + testImport("void declToImport() { int b; switch (b) { case 1: break; } }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl(hasBody(compoundStmt( + has(switchStmt(has(compoundStmt(has(caseStmt())); +} + TEST(ImportExpr, ImportStmtExpr) { MatchVerifier Verifier; // NOTE: has() ignores implicit casts, using hasDescendant() to match it Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -3983,12 +3983,16 @@ Expr *ToRHS = Importer.Import(S->getRHS()); if (!ToRHS && S->getRHS()) return nullptr; + Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); + if (!ToSubStmt && S->getSubStmt()) +return nullptr; SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc()); SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc()); SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); - return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS, -ToCaseLoc, ToEllipsisLoc, -ToColonLoc); + CaseStmt *ToStmt = new (Importer.getToContext()) + CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc); + ToStmt->setSubStmt(ToSubStmt); + return ToStmt; } Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) { Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -97,6 +97,9 @@ llvm::raw_svector_ostream ToNothing(ImportChecker); ToCtx.getTranslationUnitDecl()->print(ToNothing); + // This might catch other cases. + Imported->dump(ToNothing); + return Verifier.match(Imported, AMatcher); } @@ -267,6 +270,15 @@ hasUnaryOperand(cxxThisExpr(); } +TEST(ImportExpr, ImportSwitch) { + MatchVerifier Verifier; + EXPECT_TRUE( + testImport("void declToImport() { int b; switch (b) { case 1: break; } }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl(hasBody(compoundStmt( + has(switchStmt(has(compoundStmt(has(caseStmt())); +} + TEST(ImportExpr, ImportStmtExpr) { MatchVerifier Verifier; // NOTE: has() ignores implicit casts, using hasDescendant() to match it Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -3983,12 +3983,16 @@ Expr *ToRHS = Importer.Import(S->getRHS()); if (!ToRHS && S->getRHS()) return nullptr; + Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); + if (!ToSubStmt && S->getSubStmt()) +return nullptr; SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc()); SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc()); SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); - return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS, -ToCaseLoc, ToEllipsisLoc, -ToColonLoc); + CaseStmt *ToStmt = new (Importer.getToContext()) + CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc); + ToStmt->setSubStmt(ToSubStmt); + return ToStmt; } Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38893: [change-namespace] do not change type locs in defaulted functions.
hokein accepted this revision. hokein added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D38893 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38893: [change-namespace] do not change type locs in defaulted functions.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315892: [change-namespace] do not change type locs in defaulted functions. (authored by ioeric). Repository: rL LLVM https://reviews.llvm.org/D38893 Files: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp === --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp +++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp @@ -2093,6 +2093,68 @@ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, DefaultMoveConstructors) { + std::string Code = "namespace na {\n" + "class B {\n" + " public:\n" + " B() = default;\n" + " // Allow move only.\n" + " B(B&&) = default;\n" + " B& operator=(B&&) = default;\n" + " B(const B&) = delete;\n" + " B& operator=(const B&) = delete;\n" + " private:\n" + " int ref_;\n" + "};\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "class A {\n" + "public:\n" + " A() = default;\n" + " A(A&&) = default;\n" + " A& operator=(A&&) = default;\n" + "private:\n" + " B b;\n" + " A(const A&) = delete;\n" + " A& operator=(const A&) = delete;\n" + "};\n" + "void f() { A a; a = A(); A aa = A(); }\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class B {\n" + " public:\n" + " B() = default;\n" + " // Allow move only.\n" + " B(B&&) = default;\n" + " B& operator=(B&&) = default;\n" + " B(const B&) = delete;\n" + " B& operator=(const B&) = delete;\n" + " private:\n" + " int ref_;\n" + "};\n" + "} // namespace na\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "class A {\n" + "public:\n" + " A() = default;\n" + " A(A&&) = default;\n" + " A& operator=(A&&) = default;\n" + "private:\n" + " na::B b;\n" + " A(const A&) = delete;\n" + " A& operator=(const A&) = delete;\n" + "};\n" + "void f() { A a; a = A(); A aa = A(); }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + + } // anonymous namespace } // namespace change_namespace } // namespace clang Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp === --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp @@ -427,7 +427,8 @@ unless(templateSpecializationType())), hasParent(nestedNameSpecifierLoc()), hasAncestor(isImplicit()), - hasAncestor(UsingShadowDeclInClass))), + hasAncestor(UsingShadowDeclInClass), + hasAncestor(functionDecl(isDefaulted(), hasAncestor(decl().bind("dc"))) .bind("type"), this); @@ -451,6 +452,7 @@ specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"), unless(anyOf(hasAncestor(isImplicit()), hasAncestor(UsingShadowDeclInClass), + hasAncestor(functionDecl(isDefaulted())), hasAncestor(typeLoc(loc(qualType(hasDeclaration( decl(equalsBoundNode("from_decl")) .bind("nested_specifier_loc"), Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp === ---
[clang-tools-extra] r315892 - [change-namespace] do not change type locs in defaulted functions.
Author: ioeric Date: Mon Oct 16 01:20:10 2017 New Revision: 315892 URL: http://llvm.org/viewvc/llvm-project?rev=315892&view=rev Log: [change-namespace] do not change type locs in defaulted functions. Reviewers: hokein Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D38893 Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp?rev=315892&r1=315891&r2=315892&view=diff == --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp (original) +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp Mon Oct 16 01:20:10 2017 @@ -427,7 +427,8 @@ void ChangeNamespaceTool::registerMatche unless(templateSpecializationType())), hasParent(nestedNameSpecifierLoc()), hasAncestor(isImplicit()), - hasAncestor(UsingShadowDeclInClass))), + hasAncestor(UsingShadowDeclInClass), + hasAncestor(functionDecl(isDefaulted(), hasAncestor(decl().bind("dc"))) .bind("type"), this); @@ -451,6 +452,7 @@ void ChangeNamespaceTool::registerMatche specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"), unless(anyOf(hasAncestor(isImplicit()), hasAncestor(UsingShadowDeclInClass), + hasAncestor(functionDecl(isDefaulted())), hasAncestor(typeLoc(loc(qualType(hasDeclaration( decl(equalsBoundNode("from_decl")) .bind("nested_specifier_loc"), Modified: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp?rev=315892&r1=315891&r2=315892&view=diff == --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp (original) +++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Mon Oct 16 01:20:10 2017 @@ -2093,6 +2093,68 @@ TEST_F(ChangeNamespaceTest, TypeAsTempla EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, DefaultMoveConstructors) { + std::string Code = "namespace na {\n" + "class B {\n" + " public:\n" + " B() = default;\n" + " // Allow move only.\n" + " B(B&&) = default;\n" + " B& operator=(B&&) = default;\n" + " B(const B&) = delete;\n" + " B& operator=(const B&) = delete;\n" + " private:\n" + " int ref_;\n" + "};\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "class A {\n" + "public:\n" + " A() = default;\n" + " A(A&&) = default;\n" + " A& operator=(A&&) = default;\n" + "private:\n" + " B b;\n" + " A(const A&) = delete;\n" + " A& operator=(const A&) = delete;\n" + "};\n" + "void f() { A a; a = A(); A aa = A(); }\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class B {\n" + " public:\n" + " B() = default;\n" + " // Allow move only.\n" + " B(B&&) = default;\n" + " B& operator=(B&&) = default;\n" + " B(const B&) = delete;\n" + " B& operator=(const B&) = delete;\n" + " private:\n" + " int ref_;\n" + "};\n" + "} // namespace na\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "class A {\n" + "public:\n" + " A() = default;\n" + " A(A&&) = default;\n" + " A& operator=(A&&) = default;\n" + "private:\n" + " na::B b;\n" + " A(con
[PATCH] D34272: [Tooling] A new framework for executing clang frontend actions.
ioeric updated this revision to Diff 119117. ioeric added a comment. - clang-format code. https://reviews.llvm.org/D34272 Files: include/clang/Tooling/CommonOptionsParser.h include/clang/Tooling/Execution.h include/clang/Tooling/ToolExecutorPluginRegistry.h include/clang/Tooling/Tooling.h lib/Tooling/CMakeLists.txt lib/Tooling/CommonOptionsParser.cpp lib/Tooling/Execution.cpp lib/Tooling/Tooling.cpp unittests/Tooling/ToolingTest.cpp Index: unittests/Tooling/ToolingTest.cpp === --- unittests/Tooling/ToolingTest.cpp +++ unittests/Tooling/ToolingTest.cpp @@ -7,14 +7,18 @@ // //===--===// +#include "gmock/gmock.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Execution.h" +#include "clang/Tooling/ToolExecutorPluginRegistry.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" @@ -25,6 +29,8 @@ #include #include +using testing::ElementsAre; + namespace clang { namespace tooling { @@ -60,6 +66,60 @@ private: bool * const FoundTopLevelDecl; }; + +// This traverses the AST and outputs function name as key and "1" as value for +// each function declaration. +class ASTConsumerWithResult +: public ASTConsumer, + public RecursiveASTVisitor { +public: + using ASTVisitor = RecursiveASTVisitor; + + explicit ASTConsumerWithResult(ToolResults *Results) : Results(Results) { +assert(Results != nullptr); + } + + void HandleTranslationUnit(clang::ASTContext &Context) override { +TraverseDecl(Context.getTranslationUnitDecl()); + } + + bool TraverseFunctionDecl(clang::FunctionDecl *Decl) { +Results->addResult(Decl->getNameAsString(), "1"); +return ASTVisitor::TraverseFunctionDecl(Decl); + } + +private: + ToolResults *const Results; +}; + +class ReportResultAction : public ASTFrontendAction { +public: + explicit ReportResultAction(ToolResults *Results) : Results(Results) { +assert(Results != nullptr); + } + +protected: + std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &compiler, +llvm::StringRef /* dummy */) override { +std::unique_ptr ast_consumer{ +new ASTConsumerWithResult(Results)}; +return ast_consumer; + } + +private: + ToolResults *const Results; +}; + +class ReportResultActionFactory : public FrontendActionFactory { +public: + ReportResultActionFactory(ToolResults *Results) : Results(Results) {} + FrontendAction *create() override { return new ReportResultAction(Results); } + +private: + ToolResults *const Results; +}; + } // end namespace TEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) { @@ -533,5 +593,168 @@ } #endif +inline llvm::Error make_string_error(const llvm::Twine &Message) { + return llvm::make_error(Message, + llvm::inconvertibleErrorCode()); +} + +class TestToolExecutor : public ToolExecutor { +public: + static const char *ExecutorName; + + TestToolExecutor(std::unique_ptr Options) + : OptionsParser(std::move(Options)) {} + + llvm::StringRef getExecutorName() const override { return ExecutorName; } + + llvm::Error Execute(const ExecutionConfig &) override { +return llvm::Error::success(); + } + + ToolResults *getToolResults() override { return nullptr; }; + + llvm::ArrayRef getSourcePaths() const { +return OptionsParser->getSourcePathList(); + } + + void mapVirtualFile(StringRef FilePath, StringRef Content) override { +VFS[FilePath] = Content; + } + +private: + std::unique_ptr OptionsParser; + std::string SourcePaths; + std::map VFS; +}; + +const char *TestToolExecutor::ExecutorName = "TestToolExecutor"; + +class TestToolExecutorPlugin : public ToolExecutorPlugin { +public: + llvm::Expected> + create(int &argc, const char **argv, + llvm::cl::OptionCategory &Category) override { +static llvm::cl::opt TestExecutor( +"test_executor", llvm::cl::desc("Use TestToolExecutor")); +auto OptionsParser = llvm::make_unique( +argc, argv, Category, llvm::cl::OneOrMore, /*Overview=*/nullptr, +/*ExitOnError=*/false); +if (OptionsParser->hasError()) + return make_string_error("[TestToolExecutorPlugin] " + + OptionsParser->getErrorMessage()); +if (!TestExecutor) + return make_string_error( + "[TestToolExecutorPlugin] --test_executor is not set."); +return llvm::make_unique(std::move(OptionsParser)); + } +}; + +// This anchor is used to force the linker to link in the generated object
[PATCH] D37695: [clang-format] Break non-trailing comments, try 2
This revision was automatically updated to reflect the committed changes. Closed by commit rL315893: [clang-format] Break non-trailing comments, try 2 (authored by krasimir). Repository: rL LLVM https://reviews.llvm.org/D37695 Files: cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/lib/Format/BreakableToken.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/ContinuationIndenter.h cfe/trunk/unittests/Format/FormatTestComments.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Index: cfe/trunk/lib/Format/BreakableToken.h === --- cfe/trunk/lib/Format/BreakableToken.h +++ cfe/trunk/lib/Format/BreakableToken.h @@ -58,6 +58,8 @@ /// operations that might be executed before the main line breaking occurs: /// - getSplitBefore, for finding a split such that the content preceding it /// needs to be specially reflown, +/// - introducesBreakBefore, for checking if reformatting the beginning +/// of the content introduces a line break before it, /// - getLineLengthAfterSplitBefore, for calculating the line length in columns /// of the remainder of the content after the beginning of the content has /// been reformatted, and @@ -135,6 +137,12 @@ return Split(StringRef::npos, 0); } + /// \brief Returns if a break before the content at \p LineIndex will be + /// inserted after the whitespace preceding the content has been reformatted. + virtual bool introducesBreakBefore(unsigned LineIndex) const { +return false; + } + /// \brief Returns the number of columns required to format the piece of line /// at \p LineIndex after the content preceding the whitespace range specified /// \p SplitBefore has been reformatted, but before any breaks are made to @@ -339,6 +347,7 @@ Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit, llvm::Regex &CommentPragmasRegex) const override; + bool introducesBreakBefore(unsigned LineIndex) const override; unsigned getLineLengthAfterSplitBefore(unsigned LineIndex, unsigned TailOffset, unsigned PreviousEndColumn, Index: cfe/trunk/lib/Format/BreakableToken.cpp === --- cfe/trunk/lib/Format/BreakableToken.cpp +++ cfe/trunk/lib/Format/BreakableToken.cpp @@ -599,6 +599,12 @@ } } +bool BreakableBlockComment::introducesBreakBefore(unsigned LineIndex) const { + // A break is introduced when we want delimiters on newline. + return LineIndex == 0 && DelimitersOnNewline && + Lines[0].substr(1).find_first_not_of(Blanks) != StringRef::npos; +} + void BreakableBlockComment::replaceWhitespaceBefore( unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit, Split SplitBefore, WhitespaceManager &Whitespaces) { Index: cfe/trunk/lib/Format/ContinuationIndenter.h === --- cfe/trunk/lib/Format/ContinuationIndenter.h +++ cfe/trunk/lib/Format/ContinuationIndenter.h @@ -318,6 +318,9 @@ /// \brief \c true if this line contains a continued for-loop section. bool LineContainsContinuedForLoopSection; + /// \brief \c true if \p NextToken should not continue this line. + bool NoContinuation; + /// \brief The \c NestingLevel at the start of this line. unsigned StartOfLineLevel; @@ -364,6 +367,8 @@ if (LineContainsContinuedForLoopSection != Other.LineContainsContinuedForLoopSection) return LineContainsContinuedForLoopSection; +if (NoContinuation != Other.NoContinuation) + return NoContinuation; if (StartOfLineLevel != Other.StartOfLineLevel) return StartOfLineLevel < Other.StartOfLineLevel; if (LowestLevelOnLine != Other.LowestLevelOnLine) Index: cfe/trunk/lib/Format/ContinuationIndenter.cpp === --- cfe/trunk/lib/Format/ContinuationIndenter.cpp +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp @@ -106,6 +106,7 @@ /*AvoidBinPacking=*/false, /*NoLineBreak=*/false)); State.LineContainsContinuedForLoopSection = false; + State.NoContinuation = false; State.StartOfStringLiteral = 0; State.StartOfLineLevel = 0; State.LowestLevelOnLine = 0; @@ -322,6 +323,12 @@ Previous.TokenText == "\'\\n\'" return true; + if (Previous.is(TT_BlockComment) && Previous.IsMultiline) +return true; + + if (State.NoContinuation) +return true; + return false; } @@ -331,6 +338,8 @@ const FormatToken &Current = *State.NextToken; assert(!State.Stack.empty()); + State.NoContinuation = false; + if ((Current.is(TT_ImplicitStringLiteral) && (Current.Previous->Tok.getIdentifierInfo() == nullptr ||
r315893 - [clang-format] Break non-trailing comments, try 2
Author: krasimir Date: Mon Oct 16 02:08:53 2017 New Revision: 315893 URL: http://llvm.org/viewvc/llvm-project?rev=315893&view=rev Log: [clang-format] Break non-trailing comments, try 2 Summary: This patch enables `BreakableToken` to manage the formatting of non-trailing block comments. It is a refinement of https://reviews.llvm.org/D37007. We discovered that the optimizer outsmarts us on cases where breaking the comment costs considerably less than breaking after the comment. This patch addresses this by ensuring that a newline is inserted between a block comment and the next token. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D37695 Modified: cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/lib/Format/BreakableToken.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/ContinuationIndenter.h cfe/trunk/unittests/Format/FormatTestComments.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Modified: cfe/trunk/lib/Format/BreakableToken.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.cpp?rev=315893&r1=315892&r2=315893&view=diff == --- cfe/trunk/lib/Format/BreakableToken.cpp (original) +++ cfe/trunk/lib/Format/BreakableToken.cpp Mon Oct 16 02:08:53 2017 @@ -599,6 +599,12 @@ unsigned BreakableBlockComment::getLineL } } +bool BreakableBlockComment::introducesBreakBefore(unsigned LineIndex) const { + // A break is introduced when we want delimiters on newline. + return LineIndex == 0 && DelimitersOnNewline && + Lines[0].substr(1).find_first_not_of(Blanks) != StringRef::npos; +} + void BreakableBlockComment::replaceWhitespaceBefore( unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit, Split SplitBefore, WhitespaceManager &Whitespaces) { Modified: cfe/trunk/lib/Format/BreakableToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.h?rev=315893&r1=315892&r2=315893&view=diff == --- cfe/trunk/lib/Format/BreakableToken.h (original) +++ cfe/trunk/lib/Format/BreakableToken.h Mon Oct 16 02:08:53 2017 @@ -58,6 +58,8 @@ struct FormatStyle; /// operations that might be executed before the main line breaking occurs: /// - getSplitBefore, for finding a split such that the content preceding it /// needs to be specially reflown, +/// - introducesBreakBefore, for checking if reformatting the beginning +/// of the content introduces a line break before it, /// - getLineLengthAfterSplitBefore, for calculating the line length in columns /// of the remainder of the content after the beginning of the content has /// been reformatted, and @@ -135,6 +137,12 @@ public: return Split(StringRef::npos, 0); } + /// \brief Returns if a break before the content at \p LineIndex will be + /// inserted after the whitespace preceding the content has been reformatted. + virtual bool introducesBreakBefore(unsigned LineIndex) const { +return false; + } + /// \brief Returns the number of columns required to format the piece of line /// at \p LineIndex after the content preceding the whitespace range specified /// \p SplitBefore has been reformatted, but before any breaks are made to @@ -339,6 +347,7 @@ public: Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit, llvm::Regex &CommentPragmasRegex) const override; + bool introducesBreakBefore(unsigned LineIndex) const override; unsigned getLineLengthAfterSplitBefore(unsigned LineIndex, unsigned TailOffset, unsigned PreviousEndColumn, Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=315893&r1=315892&r2=315893&view=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Mon Oct 16 02:08:53 2017 @@ -106,6 +106,7 @@ LineState ContinuationIndenter::getIniti /*AvoidBinPacking=*/false, /*NoLineBreak=*/false)); State.LineContainsContinuedForLoopSection = false; + State.NoContinuation = false; State.StartOfStringLiteral = 0; State.StartOfLineLevel = 0; State.LowestLevelOnLine = 0; @@ -322,6 +323,12 @@ bool ContinuationIndenter::mustBreak(con Previous.TokenText == "\'\\n\'" return true; + if (Previous.is(TT_BlockComment) && Previous.IsMultiline) +return true; + + if (State.NoContinuation) +return true; + return false; } @@ -331,6 +338,8 @@ uns
[PATCH] D38882: [clang-rename] Add function unit tests.
hokein updated this revision to Diff 119121. hokein added a comment. Update, and add one unfixed testcase. https://reviews.llvm.org/D38882 Files: lib/Tooling/Refactoring/Rename/USRLocFinder.cpp unittests/Rename/CMakeLists.txt unittests/Rename/RenameClassTest.cpp unittests/Rename/RenameFunctionTest.cpp Index: unittests/Rename/RenameFunctionTest.cpp === --- /dev/null +++ unittests/Rename/RenameFunctionTest.cpp @@ -0,0 +1,555 @@ +//===-- RenameFunctionTest.cpp - unit tests for renaming functions ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "ClangRenameTest.h" + +namespace clang { +namespace clang_rename { +namespace test { +namespace { + +class RenameFunctionTest : public ClangRenameTest { +public: + RenameFunctionTest() { +AppendToHeader(R"( + struct A { +static bool Foo(); +static bool Spam(); + }; + struct B { +static void Same(); +static bool Foo(); +static int Eric(int x); + }; + void Same(int x); + int Eric(int x); + namespace base { +void Same(); +void ToNanoSeconds(); +void ToInt64NanoSeconds(); + })"); + } +}; + +TEST_F(RenameFunctionTest, RefactorsAFoo) { + std::string Before = R"( + void f() { +A::Foo(); +::A::Foo(); + })"; + std::string Expected = R"( + void f() { +A::Bar(); +::A::Bar(); + })"; + + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsNonCallingAFoo) { + std::string Before = R"( + bool g(bool (*func)()) { +return func(); + } + void f() { +auto *ref1 = A::Foo; +auto *ref2 = ::A::Foo; +g(A::Foo); + })"; + std::string Expected = R"( + bool g(bool (*func)()) { +return func(); + } + void f() { +auto *ref1 = A::Bar; +auto *ref2 = ::A::Bar; +g(A::Bar); + })"; + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsEric) { + std::string Before = R"( + void f() { +if (Eric(3)==4) ::Eric(2); + })"; + std::string Expected = R"( + void f() { +if (Larry(3)==4) ::Larry(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsNonCallingEric) { + std::string Before = R"( +int g(int (*func)(int)) { + return func(1); +} +void f() { + auto *ref = ::Eric; + g(Eric); +})"; + std::string Expected = R"( +int g(int (*func)(int)) { + return func(1); +} +void f() { + auto *ref = ::Larry; + g(Larry); +})"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorBFoo) { + std::string Before = R"( + void f() { +B::Foo(); + })"; + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Before, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorBEric) { + std::string Before = R"( + void f() { +B::Eric(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Before, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorCEric) { + std::string Before = R"( + namespace C { int Eric(int x); } + void f() { +if (C::Eric(3)==4) ::C::Eric(2); + })"; + std::string Expected = R"( + namespace C { int Eric(int x); } + void f() { +if (C::Eric(3)==4) ::C::Eric(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorEricInNamespaceC) { + std::string Before = R"( + namespace C { + int Eric(int x); + void f() { + if (Eric(3)==4) Eric(2); + } + } // namespace C)"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Before, After); +} + +TEST_F(RenameFunctionTest, NamespaceQualified) { + std::string Before = R"( + void f() { +base::ToNanoSeconds(); +::base::ToNanoSeconds(); + } + void g() { +using base::ToNanoSeconds; +base::ToNanoSeconds(); +::base::ToNanoSeconds(); +ToNanoSeconds(); + } + namespace foo { +namespace base { + void ToNanoSeconds(); + void f()
[PATCH] D38882: [clang-rename] Add function unit tests.
hokein added a comment. Sorry, I thought I have run all the tests. The previous version broke one test in RenameClass. We still need the workaround for the `std::function` special case. I added it back, and also added a corresponding test case for renaming function, but it is currently not supported and disabled, I think it is fine now, as it is a rare case IMO. Please take a look again. https://reviews.llvm.org/D38882 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34272: [Tooling] A new framework for executing clang frontend actions.
ioeric added a comment. Thanks for the review! Comment at: include/clang/Tooling/CommonOptionsParser.h:109 + + const std::string &getErrorMessage() const { return ErrorMessage; } + hokein wrote: > return `llvm::StringRef`? I'm not a big fan of `StringRef` as a return value. Callers can simply use `StringRef s = parser.getErrorMessage()`, if they want to; otherwise, they would need to worry about the live time of `s` in `auto s = parser.getErrorMessage()`, if the interface returns a `StringRef`. Comment at: include/clang/Tooling/Execution.h:47 +virtual ~ToolResults() {} +virtual void addResult(llvm::StringRef Key, llvm::StringRef Value) = 0; +virtual std::vector> AllKVResults() = 0; hokein wrote: > How about using `std::pair` type here? It would > make it consistent with the `allKVResults` below. > > Also I think we can define an alias `KVResult` for this type. > > It would make the the interface a bit cumbersome to use - callers would need to make pairs all the time. And converting to pairs is an unnecessary performance overhead IMO. The consistency with `AllKVResults` is not that important after all. We don't have a lot usages of `std::pair` yet. I'll add an alias when needed. Currently, I think it makes sense to keep the result type explicit. Comment at: include/clang/Tooling/Execution.h:48 +virtual void addResult(llvm::StringRef Key, llvm::StringRef Value) = 0; +virtual std::vector> AllKVResults() = 0; +virtual void hokein wrote: > nit: `all` I think for-each is a more canonical name? E.g. we have `for_each` loop in C++. Comment at: lib/Tooling/Execution.cpp:61 +if (!Executor) { + OS << "Failed to create '" << I->getName() + << "': " << llvm::toString(Executor.takeError()) << "\n"; hokein wrote: > Consider we have two plugins, the first iteration fails, and the second one > succeeds, the code looks like still treating it as an error here? And if the > case where there are more than one executor being created successfully, we > just return the first one. > > My understanding of the createExecutorFromCommandLineArgs's behavior is to > find a proper `ToolExecutorPlugin` and create a `ToolExecutor` instance. > > Maybe add a command-line flag like `--executor=` to make it > straightforward to choose which registered executor is used, and make > `StandaloneToolExecutor` as default? Yes, we simply return the first plugin that matches. It's hard to ensure that all executors have mutually exclusive arguments when more executors are added; it should be up to the executors to define unique (or as-unique-as-possible) arguments. For example, a map-reduce-based executor could require a "--mr" option to be set. The factory should simply return the first one that matches. The point of this helper function is to hide the dispatching of different executors, so I don't think requiring users to specify the executor name is sensible. For example, users should only care about whether to set `--mr` instead of having to know the existence of different executors. Comment at: unittests/Tooling/ToolingTest.cpp:638 + llvm::cl::OptionCategory &Category) override { +static llvm::cl::opt TestExecutor( +"test_executor", llvm::cl::desc("Use TestToolExecutor")); hokein wrote: > any reason to make it static? Added a comment explaining this. Comment at: unittests/Tooling/ToolingTest.cpp:667 + std::vector argv = {"prog", "--fake_flag_no_no_no", "f"}; + int argc = argv.size(); + auto Executor = hokein wrote: > nit: size_t, the same below. `createExecutorFromCommandLineArgs` and, more importantly, the underlying library functions take `int`, so... :( https://reviews.llvm.org/D34272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34272: [Tooling] A new framework for executing clang frontend actions.
ioeric updated this revision to Diff 119122. ioeric marked 5 inline comments as done. ioeric added a comment. - Address review comments. https://reviews.llvm.org/D34272 Files: include/clang/Tooling/CommonOptionsParser.h include/clang/Tooling/Execution.h include/clang/Tooling/ToolExecutorPluginRegistry.h include/clang/Tooling/Tooling.h lib/Tooling/CMakeLists.txt lib/Tooling/CommonOptionsParser.cpp lib/Tooling/Execution.cpp lib/Tooling/Tooling.cpp unittests/Tooling/ToolingTest.cpp Index: unittests/Tooling/ToolingTest.cpp === --- unittests/Tooling/ToolingTest.cpp +++ unittests/Tooling/ToolingTest.cpp @@ -7,14 +7,18 @@ // //===--===// +#include "gmock/gmock.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Execution.h" +#include "clang/Tooling/ToolExecutorPluginRegistry.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" @@ -60,6 +64,60 @@ private: bool * const FoundTopLevelDecl; }; + +// This traverses the AST and outputs function name as key and "1" as value for +// each function declaration. +class ASTConsumerWithResult +: public ASTConsumer, + public RecursiveASTVisitor { +public: + using ASTVisitor = RecursiveASTVisitor; + + explicit ASTConsumerWithResult(ToolResults *Results) : Results(Results) { +assert(Results != nullptr); + } + + void HandleTranslationUnit(clang::ASTContext &Context) override { +TraverseDecl(Context.getTranslationUnitDecl()); + } + + bool TraverseFunctionDecl(clang::FunctionDecl *Decl) { +Results->addResult(Decl->getNameAsString(), "1"); +return ASTVisitor::TraverseFunctionDecl(Decl); + } + +private: + ToolResults *const Results; +}; + +class ReportResultAction : public ASTFrontendAction { +public: + explicit ReportResultAction(ToolResults *Results) : Results(Results) { +assert(Results != nullptr); + } + +protected: + std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &compiler, +llvm::StringRef /* dummy */) override { +std::unique_ptr ast_consumer{ +new ASTConsumerWithResult(Results)}; +return ast_consumer; + } + +private: + ToolResults *const Results; +}; + +class ReportResultActionFactory : public FrontendActionFactory { +public: + ReportResultActionFactory(ToolResults *Results) : Results(Results) {} + FrontendAction *create() override { return new ReportResultAction(Results); } + +private: + ToolResults *const Results; +}; + } // end namespace TEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) { @@ -533,5 +591,170 @@ } #endif +inline llvm::Error make_string_error(const llvm::Twine &Message) { + return llvm::make_error(Message, + llvm::inconvertibleErrorCode()); +} + +class TestToolExecutor : public ToolExecutor { +public: + static const char *ExecutorName; + + TestToolExecutor(std::unique_ptr Options) + : OptionsParser(std::move(Options)) {} + + llvm::StringRef getExecutorName() const override { return ExecutorName; } + + llvm::Error execute(const ExecutionConfig &) override { +return llvm::Error::success(); + } + + ToolResults *getToolResults() override { return nullptr; }; + + llvm::ArrayRef getSourcePaths() const { +return OptionsParser->getSourcePathList(); + } + + void mapVirtualFile(StringRef FilePath, StringRef Content) override { +VFS[FilePath] = Content; + } + +private: + std::unique_ptr OptionsParser; + std::string SourcePaths; + std::map VFS; +}; + +const char *TestToolExecutor::ExecutorName = "TestToolExecutor"; + +class TestToolExecutorPlugin : public ToolExecutorPlugin { +public: + llvm::Expected> + create(int &argc, const char **argv, + llvm::cl::OptionCategory &Category) override { +// FIXME: Using static option here because `opt`s could not be ungirestered +// properly. The static option seems to work fine for now. +static llvm::cl::opt TestExecutor( +"test_executor", llvm::cl::desc("Use TestToolExecutor")); +auto OptionsParser = llvm::make_unique( +argc, argv, Category, llvm::cl::OneOrMore, /*Overview=*/nullptr, +/*ExitOnError=*/false); +if (OptionsParser->hasError()) + return make_string_error("[TestToolExecutorPlugin] " + + OptionsParser->getErrorMessage()); +if (!TestExecutor) + return make_string_error( + "[TestToolExecutorPlugin] --test_executor is not set."); +return llvm::make_unique(std::move(OptionsParser)); + } +};
[PATCH] D38882: [clang-rename] Add function unit tests.
ioeric accepted this revision. ioeric added a comment. Still LGTM Comment at: lib/Tooling/Refactoring/Rename/USRLocFinder.cpp:469 + // name. + // FIXME: Consider using using-decls to shorten the namespace + // qualifers. The current behavior looks fine to me, but I'm not sure if this is a right `FIXME`? Basically, I think we want to be able to get the real `DeclContext` for the symbol reference here right? https://reviews.llvm.org/D38882 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38882: [clang-rename] Add function unit tests.
hokein updated this revision to Diff 119128. hokein marked an inline comment as done. hokein added a comment. Remove the FIXME. https://reviews.llvm.org/D38882 Files: lib/Tooling/Refactoring/Rename/USRLocFinder.cpp unittests/Rename/CMakeLists.txt unittests/Rename/RenameClassTest.cpp unittests/Rename/RenameFunctionTest.cpp Index: unittests/Rename/RenameFunctionTest.cpp === --- /dev/null +++ unittests/Rename/RenameFunctionTest.cpp @@ -0,0 +1,555 @@ +//===-- RenameFunctionTest.cpp - unit tests for renaming functions ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "ClangRenameTest.h" + +namespace clang { +namespace clang_rename { +namespace test { +namespace { + +class RenameFunctionTest : public ClangRenameTest { +public: + RenameFunctionTest() { +AppendToHeader(R"( + struct A { +static bool Foo(); +static bool Spam(); + }; + struct B { +static void Same(); +static bool Foo(); +static int Eric(int x); + }; + void Same(int x); + int Eric(int x); + namespace base { +void Same(); +void ToNanoSeconds(); +void ToInt64NanoSeconds(); + })"); + } +}; + +TEST_F(RenameFunctionTest, RefactorsAFoo) { + std::string Before = R"( + void f() { +A::Foo(); +::A::Foo(); + })"; + std::string Expected = R"( + void f() { +A::Bar(); +::A::Bar(); + })"; + + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsNonCallingAFoo) { + std::string Before = R"( + bool g(bool (*func)()) { +return func(); + } + void f() { +auto *ref1 = A::Foo; +auto *ref2 = ::A::Foo; +g(A::Foo); + })"; + std::string Expected = R"( + bool g(bool (*func)()) { +return func(); + } + void f() { +auto *ref1 = A::Bar; +auto *ref2 = ::A::Bar; +g(A::Bar); + })"; + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsEric) { + std::string Before = R"( + void f() { +if (Eric(3)==4) ::Eric(2); + })"; + std::string Expected = R"( + void f() { +if (Larry(3)==4) ::Larry(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsNonCallingEric) { + std::string Before = R"( +int g(int (*func)(int)) { + return func(1); +} +void f() { + auto *ref = ::Eric; + g(Eric); +})"; + std::string Expected = R"( +int g(int (*func)(int)) { + return func(1); +} +void f() { + auto *ref = ::Larry; + g(Larry); +})"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorBFoo) { + std::string Before = R"( + void f() { +B::Foo(); + })"; + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Before, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorBEric) { + std::string Before = R"( + void f() { +B::Eric(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Before, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorCEric) { + std::string Before = R"( + namespace C { int Eric(int x); } + void f() { +if (C::Eric(3)==4) ::C::Eric(2); + })"; + std::string Expected = R"( + namespace C { int Eric(int x); } + void f() { +if (C::Eric(3)==4) ::C::Eric(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, DoesNotRefactorEricInNamespaceC) { + std::string Before = R"( + namespace C { + int Eric(int x); + void f() { + if (Eric(3)==4) Eric(2); + } + } // namespace C)"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Before, After); +} + +TEST_F(RenameFunctionTest, NamespaceQualified) { + std::string Before = R"( + void f() { +base::ToNanoSeconds(); +::base::ToNanoSeconds(); + } + void g() { +using base::ToNanoSeconds; +base::ToNanoSeconds(); +::base::ToNanoSeconds(); +ToNanoSeconds(); + } + namespace foo { +namespace base { + void ToNanoSeconds()
[PATCH] D38882: [clang-rename] Add function unit tests.
hokein added inline comments. Comment at: lib/Tooling/Refactoring/Rename/USRLocFinder.cpp:469 + // name. + // FIXME: Consider using using-decls to shorten the namespace + // qualifers. ioeric wrote: > The current behavior looks fine to me, but I'm not sure if this is a right > `FIXME`? Basically, I think we want to be able to get the real `DeclContext` > for the symbol reference here right? I'm fine on removing it, as this is somewhat mentioned above. Done. https://reviews.llvm.org/D38882 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38945: [CodeGen] Pass TBAA info along with lvalue base info everywhere
kosarev created this revision. kosarev added a project: clang. This patch addresses the rest of the cases where we pass lvalue base info, but do not provide corresponding TBAA info. This patch should not bring in any functional changes. This is part of https://reviews.llvm.org/D38126 reworked to be a separate patch to make reviewing easier. Repository: rL LLVM https://reviews.llvm.org/D38945 Files: lib/CodeGen/CGAtomic.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGObjCRuntime.cpp lib/CodeGen/CGValue.h lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3081,13 +3081,6 @@ llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo, -bool isNontemporal = false) { -return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, BaseInfo, -CGM.getTBAAAccessInfo(Ty), isNontemporal); - } - - llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, -SourceLocation Loc, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isNontemporal = false); @@ -3109,13 +3102,6 @@ } void EmitStoreOfScalar(llvm::Value *Value, Address Addr, - bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, - bool isInit = false, bool isNontemporal = false) { -EmitStoreOfScalar(Value, Addr, Volatile, Ty, BaseInfo, - CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); - } - - void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isInit = false, bool isNontemporal = false); Index: lib/CodeGen/CGValue.h === --- lib/CodeGen/CGValue.h +++ lib/CodeGen/CGValue.h @@ -230,9 +230,8 @@ Expr *BaseIvarExp; private: - void Initialize(QualType Type, Qualifiers Quals, - CharUnits Alignment, LValueBaseInfo BaseInfo, - TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) { + void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment, + LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); this->Type = Type; @@ -381,24 +380,26 @@ } static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx, - QualType type, LValueBaseInfo BaseInfo) { + QualType type, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = VectorElt; R.V = vecAddress.getPointer(); R.VectorIdx = Idx; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo); + BaseInfo, TBAAInfo); return R; } static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts, - QualType type, LValueBaseInfo BaseInfo) { + QualType type, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = ExtVectorElt; R.V = vecAddress.getPointer(); R.VectorElts = Elts; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo); + BaseInfo, TBAAInfo); return R; } @@ -408,24 +409,25 @@ /// bit-field refers to. /// \param Info - The information describing how to perform the bit-field /// access. - static LValue MakeBitfield(Address Addr, - const CGBitFieldInfo &Info, - QualType type, - LValueBaseInfo BaseInfo) { + static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info, + QualType type, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = BitField; R.V = Addr.getPointer(); R.BitFieldInfo = &Info; -R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo); +R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo, + TBAAInfo); return R; } static LValue MakeGlobalReg(Address Reg, QualType type) { LValue R; R.LVType = GlobalReg; R.V = Reg.getPointer(); R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource
[PATCH] D38882: [clang-rename] Add function unit tests.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315898: [clang-rename] Add function unit tests. (authored by hokein). Repository: rL LLVM https://reviews.llvm.org/D38882 Files: cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp cfe/trunk/unittests/Rename/CMakeLists.txt cfe/trunk/unittests/Rename/RenameClassTest.cpp cfe/trunk/unittests/Rename/RenameFunctionTest.cpp Index: cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp === --- cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp +++ cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp @@ -194,6 +194,12 @@ bool VisitDeclRefExpr(const DeclRefExpr *Expr) { const NamedDecl *Decl = Expr->getFoundDecl(); +// Get the underlying declaration of the shadow declaration introduced by a +// using declaration. +if (auto* UsingShadow = llvm::dyn_cast(Decl)) { + Decl = UsingShadow->getTargetDecl(); +} + if (isInUSRSet(Decl)) { RenameInfo Info = {Expr->getSourceRange().getBegin(), Expr->getSourceRange().getEnd(), @@ -452,6 +458,23 @@ RenameInfo.FromDecl, NewName.startswith("::") ? NewName.str() : ("::" + NewName).str()); +} else { + // This fixes the case where type `T` is a parameter inside a function + // type (e.g. `std::function`) and the DeclContext of `T` + // becomes the translation unit. As a workaround, we simply use + // fully-qualified name here for all references whose `DeclContext` is + // the translation unit and ignore the possible existence of + // using-decls (in the global scope) that can shorten the replaced + // name. + llvm::StringRef ActualName = Lexer::getSourceText( + CharSourceRange::getTokenRange( + SourceRange(RenameInfo.Begin, RenameInfo.End)), + SM, TranslationUnitDecl->getASTContext().getLangOpts()); + // Add the leading "::" back if the name written in the code contains + // it. + if (ActualName.startswith("::") && !NewName.startswith("::")) { +ReplacedName = "::" + NewName.str(); + } } } // If the NewName contains leading "::", add it back. Index: cfe/trunk/unittests/Rename/RenameFunctionTest.cpp === --- cfe/trunk/unittests/Rename/RenameFunctionTest.cpp +++ cfe/trunk/unittests/Rename/RenameFunctionTest.cpp @@ -0,0 +1,555 @@ +//===-- RenameFunctionTest.cpp - unit tests for renaming functions ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "ClangRenameTest.h" + +namespace clang { +namespace clang_rename { +namespace test { +namespace { + +class RenameFunctionTest : public ClangRenameTest { +public: + RenameFunctionTest() { +AppendToHeader(R"( + struct A { +static bool Foo(); +static bool Spam(); + }; + struct B { +static void Same(); +static bool Foo(); +static int Eric(int x); + }; + void Same(int x); + int Eric(int x); + namespace base { +void Same(); +void ToNanoSeconds(); +void ToInt64NanoSeconds(); + })"); + } +}; + +TEST_F(RenameFunctionTest, RefactorsAFoo) { + std::string Before = R"( + void f() { +A::Foo(); +::A::Foo(); + })"; + std::string Expected = R"( + void f() { +A::Bar(); +::A::Bar(); + })"; + + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsNonCallingAFoo) { + std::string Before = R"( + bool g(bool (*func)()) { +return func(); + } + void f() { +auto *ref1 = A::Foo; +auto *ref2 = ::A::Foo; +g(A::Foo); + })"; + std::string Expected = R"( + bool g(bool (*func)()) { +return func(); + } + void f() { +auto *ref1 = A::Bar; +auto *ref2 = ::A::Bar; +g(A::Bar); + })"; + std::string After = runClangRenameOnCode(Before, "A::Foo", "A::Bar"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsEric) { + std::string Before = R"( + void f() { +if (Eric(3)==4) ::Eric(2); + })"; + std::string Expected = R"( + void f() { +if (Larry(3)==4) ::Larry(2); + })"; + std::string After = runClangRenameOnCode(Before, "Eric", "Larry"); + CompareSnippets(Expected, After); +} + +TEST_F(RenameFunctionTest, RefactorsNonCallingEric) { + std::string Bef
r315898 - [clang-rename] Add function unit tests.
Author: hokein Date: Mon Oct 16 03:37:42 2017 New Revision: 315898 URL: http://llvm.org/viewvc/llvm-project?rev=315898&view=rev Log: [clang-rename] Add function unit tests. Summary: Also contain a fix: * Fix a false positive of renaming a using shadow function declaration. Reviewers: ioeric Reviewed By: ioeric Subscribers: klimek, mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D38882 Added: cfe/trunk/unittests/Rename/RenameFunctionTest.cpp Modified: cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp cfe/trunk/unittests/Rename/CMakeLists.txt cfe/trunk/unittests/Rename/RenameClassTest.cpp Modified: cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp?rev=315898&r1=315897&r2=315898&view=diff == --- cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp (original) +++ cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp Mon Oct 16 03:37:42 2017 @@ -194,6 +194,12 @@ public: bool VisitDeclRefExpr(const DeclRefExpr *Expr) { const NamedDecl *Decl = Expr->getFoundDecl(); +// Get the underlying declaration of the shadow declaration introduced by a +// using declaration. +if (auto* UsingShadow = llvm::dyn_cast(Decl)) { + Decl = UsingShadow->getTargetDecl(); +} + if (isInUSRSet(Decl)) { RenameInfo Info = {Expr->getSourceRange().getBegin(), Expr->getSourceRange().getEnd(), @@ -452,6 +458,23 @@ createRenameAtomicChanges(llvm::ArrayRef RenameInfo.FromDecl, NewName.startswith("::") ? NewName.str() : ("::" + NewName).str()); +} else { + // This fixes the case where type `T` is a parameter inside a function + // type (e.g. `std::function`) and the DeclContext of `T` + // becomes the translation unit. As a workaround, we simply use + // fully-qualified name here for all references whose `DeclContext` is + // the translation unit and ignore the possible existence of + // using-decls (in the global scope) that can shorten the replaced + // name. + llvm::StringRef ActualName = Lexer::getSourceText( + CharSourceRange::getTokenRange( + SourceRange(RenameInfo.Begin, RenameInfo.End)), + SM, TranslationUnitDecl->getASTContext().getLangOpts()); + // Add the leading "::" back if the name written in the code contains + // it. + if (ActualName.startswith("::") && !NewName.startswith("::")) { +ReplacedName = "::" + NewName.str(); + } } } // If the NewName contains leading "::", add it back. Modified: cfe/trunk/unittests/Rename/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Rename/CMakeLists.txt?rev=315898&r1=315897&r2=315898&view=diff == --- cfe/trunk/unittests/Rename/CMakeLists.txt (original) +++ cfe/trunk/unittests/Rename/CMakeLists.txt Mon Oct 16 03:37:42 2017 @@ -7,6 +7,7 @@ include_directories(${CLANG_SOURCE_DIR}) add_clang_unittest(ClangRenameTests RenameClassTest.cpp + RenameFunctionTest.cpp ) target_link_libraries(ClangRenameTests Modified: cfe/trunk/unittests/Rename/RenameClassTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Rename/RenameClassTest.cpp?rev=315898&r1=315897&r2=315898&view=diff == --- cfe/trunk/unittests/Rename/RenameClassTest.cpp (original) +++ cfe/trunk/unittests/Rename/RenameClassTest.cpp Mon Oct 16 03:37:42 2017 @@ -51,6 +51,7 @@ INSTANTIATE_TEST_CASE_P( testing::ValuesIn(std::vector({ // basic classes {"a::Foo f;", "b::Bar f;", "", ""}, +{"::a::Foo f;", "::b::Bar f;", "", ""}, {"void f(a::Foo f) {}", "void f(b::Bar f) {}", "", ""}, {"void f(a::Foo *f) {}", "void f(b::Bar *f) {}", "", ""}, {"a::Foo f() { return a::Foo(); }", "b::Bar f() { return b::Bar(); }", Added: cfe/trunk/unittests/Rename/RenameFunctionTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Rename/RenameFunctionTest.cpp?rev=315898&view=auto == --- cfe/trunk/unittests/Rename/RenameFunctionTest.cpp (added) +++ cfe/trunk/unittests/Rename/RenameFunctionTest.cpp Mon Oct 16 03:37:42 2017 @@ -0,0 +1,555 @@ +//===-- RenameFunctionTest.cpp - unit tests for renaming functions ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===
[PATCH] D38943: [ASTImporter] import SubStmt of CaseStmt
xazax.hun accepted this revision. xazax.hun added a comment. This revision is now accepted and ready to land. LGTM with a nit. Comment at: unittests/AST/ASTImporterTest.cpp:100 + // This might catch other cases. + Imported->dump(ToNothing); I would elaborate a bit more on the purpose of the code below. https://reviews.llvm.org/D38943 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38868: [OpenCL] Restrict swizzle length check to OpenCL mode
Anastasia accepted this revision. Anastasia added a comment. This revision is now accepted and ready to land. LGTM! Comment at: test/SemaOpenCL/vector_swizzle_length.cl:7 void foo() { -float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0); +float8 f2 = (float8){0, 0, 0, 0, 0, 0, 0, 0}; bruno wrote: > Anastasia wrote: > > Even though this works in Clang, ideally OpenCL vector literal is with > > parenthesis (see s6.1.6). > Ok. I changed this to avoid warnings in C mode. Gonna change it back, Can you undo this change please before committing. Thanks! https://reviews.llvm.org/D38868 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38947: [CodeGen] Refine generation of TBAA info for bit-field lvalues
kosarev created this revision. kosarev added a project: clang. The main change is that now we generate TBAA info before constructing the resulting lvalue instead of constructing lvalue with some default TBAA info and fixing it as necessary afterwards. We also keep the TBAA info close to lvalue base info, which is supposed to simplify their future merging. This patch should not bring in any functional changes. This is part of https://reviews.llvm.org/D38126 reworked to be a separate patch to simplify review. Repository: rL LLVM https://reviews.llvm.org/D38947 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3229,7 +3229,7 @@ llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); - LValue EmitLValueForField(LValue Base, const FieldDecl* Field); + LValue EmitLValueForField(LValue BaseExpr, const FieldDecl *Field); LValue EmitLValueForLambdaField(const FieldDecl *Field); /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3662,130 +3662,118 @@ return false; } -LValue CodeGenFunction::EmitLValueForField(LValue base, - const FieldDecl *field) { - LValueBaseInfo BaseInfo = base.getBaseInfo(); - AlignmentSource fieldAlignSource = -getFieldAlignmentSource(BaseInfo.getAlignmentSource()); - LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); +LValue CodeGenFunction::EmitLValueForField(LValue BaseExpr, + const FieldDecl *Field) { + LValueBaseInfo BaseInfo = BaseExpr.getBaseInfo(); - QualType type = field->getType(); - const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) -FieldBaseInfo.setMayAlias(true); - bool mayAlias = FieldBaseInfo.getMayAlias(); - - if (field->isBitField()) { + if (Field->isBitField()) { const CGRecordLayout &RL = - CGM.getTypes().getCGRecordLayout(field->getParent()); -const CGBitFieldInfo &Info = RL.getBitFieldInfo(field); -Address Addr = base.getAddress(); -unsigned Idx = RL.getLLVMFieldNo(field); + CGM.getTypes().getCGRecordLayout(Field->getParent()); +const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field); +Address Addr = BaseExpr.getAddress(); +unsigned Idx = RL.getLLVMFieldNo(Field); if (Idx != 0) // For structs, we GEP to the field that the record layout suggests. Addr = Builder.CreateStructGEP(Addr, Idx, Info.StorageOffset, - field->getName()); + Field->getName()); // Get the access type. llvm::Type *FieldIntTy = llvm::Type::getIntNTy(getLLVMContext(), Info.StorageSize); if (Addr.getElementType() != FieldIntTy) Addr = Builder.CreateElementBitCast(Addr, FieldIntTy); -QualType fieldType = - field->getType().withCVRQualifiers(base.getVRQualifiers()); -return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); +QualType FieldType = + Field->getType().withCVRQualifiers(BaseExpr.getVRQualifiers()); +// TODO: Support TBAA for bit fields. +LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), false); +return LValue::MakeBitfield(Addr, Info, FieldType, FieldBaseInfo); } - Address addr = base.getAddress(); - unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; - if (rec->isUnion()) { -// For unions, there is no pointer adjustment. -assert(!type->isReferenceType() && "union has reference member"); -// TODO: handle path-aware TBAA for union. -TBAAPath = false; + // Fields of may-alias structures are may-alias themselves. + // FIXME: this should get propagated down through anonymous structs + // and unions. + QualType FieldType = Field->getType(); + const RecordDecl *Rec = Field->getParent(); + AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource(); + LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource), false); + TBAAAccessInfo FieldTBAAInfo; + if (BaseInfo.getMayAlias() || Rec->hasAttr() || + FieldType->isVectorType()) { +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else if (Rec->isUnion()) { +// TODO: Support TBAA for unions. +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else { +// If no base type been assigned for the base access, then try to generate +// one for this base lvalue. +FieldTBAAInfo = BaseExpr.getTBAAInfo(); +if
[PATCH] D36471: [StaticAnalyzer] Try to calculate arithmetic result when operand has a range of possible values
danielmarjamaki added a comment. ping Repository: rL LLVM https://reviews.llvm.org/D36471 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38921: [analyzer] LoopUnrolling: update the matched assignment operators
danielmarjamaki added a comment. LGTM.. however I would like approval from somebody else also. https://reviews.llvm.org/D38921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D37437: [analyzer] Fix some checker's output plist not containing the checker name
xazax.hun updated this revision to Diff 119141. xazax.hun marked 2 inline comments as done. xazax.hun added a comment. Herald added a subscriber: szepet. - Address review comments. https://reviews.llvm.org/D37437 Files: include/clang/StaticAnalyzer/Core/BugReporter/BugType.h lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp lib/StaticAnalyzer/Checkers/CStringChecker.cpp lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp lib/StaticAnalyzer/Checkers/IteratorChecker.cpp lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h lib/StaticAnalyzer/Checkers/MallocChecker.cpp lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp lib/StaticAnalyzer/Checkers/ValistChecker.cpp test/Analysis/malloc.c Index: test/Analysis/malloc.c === --- test/Analysis/malloc.c +++ test/Analysis/malloc.c @@ -1720,13 +1720,6 @@ } } -char *dupstrWarn(const char *s) { - const int len = strlen(s); - char *p = (char*) smallocWarn(len + 1); - strcpy(p, s); // expected-warning{{String copy function overflows destination buffer}} - return p; -} - int *radar15580979() { int *data = (int *)malloc(32); int *p = data ?: (int*)malloc(32); // no warning Index: lib/StaticAnalyzer/Checkers/ValistChecker.cpp === --- lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -64,7 +64,7 @@ CheckerContext &C) const; void reportLeakedVALists(const RegionVector &LeakedVALists, StringRef Msg1, StringRef Msg2, CheckerContext &C, ExplodedNode *N, - bool ForceReport = false) const; + bool ReportUninit = false) const; void checkVAListStartCall(const CallEvent &Call, CheckerContext &C, bool IsCopy) const; @@ -267,15 +267,15 @@ void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists, StringRef Msg1, StringRef Msg2, CheckerContext &C, ExplodedNode *N, -bool ForceReport) const { +bool ReportUninit) const { if (!(ChecksEnabled[CK_Unterminated] || -(ChecksEnabled[CK_Uninitialized] && ForceReport))) +(ChecksEnabled[CK_Uninitialized] && ReportUninit))) return; for (auto Reg : LeakedVALists) { if (!BT_leakedvalist) { - BT_leakedvalist.reset(new BugType(CheckNames[CK_Unterminated], -"Leaked va_list", -categories::MemoryError)); + BT_leakedvalist.reset(new BugType( + CheckNames[ReportUninit ? CK_Uninitialized : CK_Unterminated], + "Leaked va_list", categories::MemoryError)); BT_leakedvalist->setSuppressOnSink(true); } @@ -375,7 +375,7 @@ std::shared_ptr ValistChecker::ValistBugVisitor::VisitNode( const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, -BugReport &BR) { +BugReport &) { ProgramStateRef State = N->getState(); ProgramStateRef StatePrev = PrevN->getState(); Index: lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp === --- lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp +++ lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp @@ -54,8 +54,8 @@ check::PointerEscape> { CallDescription OpenFn, CloseFn; - std::unique_ptr DoubleCloseBugType; - std::unique_ptr LeakBugType; + mutable std::unique_ptr DoubleCloseBugType; + mutable std::unique_ptr LeakBugType; void reportDoubleClose(SymbolRef FileDescSym, const CallEvent &Call, @@ -104,16 +104,7 @@ } // end anonymous namespace SimpleStreamChecker::SimpleStreamChecker() -: OpenFn("fopen"), CloseFn("fclose", 1) { - // Initialize the bug types. - DoubleCloseBugType.reset( - new BugType(this, "Double fclose", "Unix Stream API Error")); - - LeakBugType.reset( - new BugType(this, "Resource Leak", "Unix Stream API Error")); - // Sinks are higher importance bugs as well as calls to assert() or exit(0). - LeakBugType->setSuppressOnSink(true); -} +: OpenFn("fopen"), CloseFn("fclose", 1) {} void SimpleStreamChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { @@ -206,6 +197,10 @@ if (!ErrNode) return; + if (!DoubleCloseBugType) +DoubleCloseBugType.reset( +new
[PATCH] D37437: [analyzer] Fix some checker's output plist not containing the checker name
xazax.hun added inline comments. Comment at: lib/StaticAnalyzer/Checkers/CStringChecker.cpp:308 if (StOutBound && !StInBound) { +if (!Filter.CheckCStringOutOfBounds) + return state; zaks.anna wrote: > This seems to be related to the change in the test, correct? In the future, > please, split changes like this one into their own separate commits. Yes. I will do so in the future, thanks. https://reviews.llvm.org/D37437 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38801: [analyzer] In getSVal() API, disable auto-detection of void type as char type.
danielmarjamaki added a comment. LGTM https://reviews.llvm.org/D38801 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26350: Keep invalid Switch in the AST
ogoffart updated this revision to Diff 119142. ogoffart added a comment. Updated the patch so that ActOnStartOfSwitchStmt returns void, and ActOnFinishSwitchStmt will skip some checks in case of error https://reviews.llvm.org/D26350 Files: include/clang/Sema/Sema.h lib/Parse/ParseStmt.cpp lib/Sema/SemaStmt.cpp lib/Sema/TreeTransform.h test/Misc/ast-dump-invalid-switch.cpp test/SemaCXX/switch.cpp Index: test/SemaCXX/switch.cpp === --- test/SemaCXX/switch.cpp +++ test/SemaCXX/switch.cpp @@ -130,3 +130,20 @@ } } + +namespace InvalidCondition { +enum class color { red, + blue, + green }; +void test() { + // When the condition is invalid, there should be no errors or warnings + switch (invalidCode) { // expected-error {{use of undeclared identifier}} + case 0: + case -(1ll << 62) - 1: + case (1ll << 62) + 1: + case color::red: + default: +break; + } +} +} // namespace InvalidCondition Index: test/Misc/ast-dump-invalid-switch.cpp === --- /dev/null +++ test/Misc/ast-dump-invalid-switch.cpp @@ -0,0 +1,105 @@ +// RUN: not %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s + +/* This test ensures that the AST is still complete, even for invalid code */ + +namespace TestInvalidSwithCondition { +int f(int x) { + switch (_invalid_) { + case 0: +return 1; + default: +return 2; + } +} +} + +// CHECK: NamespaceDecl {{.*}} TestInvalidSwithCondition +// CHECK-NEXT: `-FunctionDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-SwitchStmt +// CHECK-NEXT: |-<<>> +// CHECK-NEXT: |-<<>> +// CHECK-NEXT: |-OpaqueValueExpr +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: |-CaseStmt +// CHECK-NEXT: | |-IntegerLiteral {{.*}} 'int' 0 +// CHECK-NEXT: | |-<<>> +// CHECK-NEXT: | `-ReturnStmt +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: `-DefaultStmt +// CHECK-NEXT: `-ReturnStmt +// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2 + +namespace TestSwitchConditionNotIntegral { +int g(int *x) { + switch (x) { + case 0: +return 1; + default: +return 2; + } +} +} + +// CHECK: NamespaceDecl {{.*}} TestSwitchConditionNotIntegral +// CHECK-NEXT: `-FunctionDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-SwitchStmt +// CHECK-NEXT: |-<<>> +// CHECK-NEXT: |-<<>> +// CHECK-NEXT: |-ImplicitCastExpr +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'x' 'int *' +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: |-CaseStmt +// CHECK-NEXT: | |-IntegerLiteral {{.*}} 'int' 0 +// CHECK-NEXT: | |-<<>> +// CHECK-NEXT: | `-ReturnStmt +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: `-DefaultStmt +// CHECK-NEXT: `-ReturnStmt +// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2 + +namespace TestSwitchInvalidCases { +int g(int x) { + switch (x) { + case _invalid_: +return 1; + case _invalid_: +return 2; + case x: +return 3; + default: +return 4; + default: +return 5; + } +} +} + +// CHECK: NamespaceDecl {{.*}} TestSwitchInvalidCases +// CHECK-NEXT: `-FunctionDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-SwitchStmt +// CHECK-NEXT: |-<<>> +// CHECK-NEXT: |-<<>> +// CHECK-NEXT: |-ImplicitCastExpr +// CHECK-NEXT: | `-DeclRefExpr {{.*}}'x' 'int' +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: |-ReturnStmt +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: |-ReturnStmt +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 2 +// CHECK-NEXT: |-CaseStmt +// CHECK-NEXT: | |-DeclRefExpr {{.*}} 'x' 'int' +// CHECK-NEXT: | |-<<>> +// CHECK-NEXT: | `-ReturnStmt +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK-NEXT: |-DefaultStmt +// CHECK-NEXT: | `-ReturnStmt +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 4 +// CHECK-NEXT: `-DefaultStmt +// CHECK-NEXT: `-ReturnStmt +// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 5 Index: lib/Sema/TreeTransform.h === --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -1256,18 +1256,17 @@ /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, Stmt *Init, -Sema::ConditionResult Cond) { -return getSema().ActOnStartOfSwitchStm
[PATCH] D38943: [ASTImporter] import SubStmt of CaseStmt
r.stahl added a comment. Thanks for the fast response. See inline comment. Comment at: unittests/AST/ASTImporterTest.cpp:100 + // This might catch other cases. + Imported->dump(ToNothing); xazax.hun wrote: > I would elaborate a bit more on the purpose of the code below. I will need help for that, since I do not have a better rationale myself. My guess would be that print has different assumptions and error checking than dump, so executing both increases coverage. https://reviews.llvm.org/D38943 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38731: [clangd] Allow to pass code completion opts to ClangdServer.
krasimir accepted this revision. krasimir added a comment. This revision is now accepted and ready to land. Great! I like the unit testing approach a lot! https://reviews.llvm.org/D38731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315902 - [CUDA] Require libdevice only if needed
Author: hahnfeld Date: Mon Oct 16 06:31:30 2017 New Revision: 315902 URL: http://llvm.org/viewvc/llvm-project?rev=315902&view=rev Log: [CUDA] Require libdevice only if needed If the user passes -nocudalib, we can live without it being present. Simplify the code by just checking whether LibDeviceMap is empty. Differential Revision: https://reviews.llvm.org/D38901 Added: cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/ cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep Modified: cfe/trunk/lib/Driver/ToolChains/Cuda.cpp cfe/trunk/test/Driver/cuda-detect.cu Modified: cfe/trunk/lib/Driver/ToolChains/Cuda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Cuda.cpp?rev=315902&r1=315901&r2=315902&view=diff == --- cfe/trunk/lib/Driver/ToolChains/Cuda.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Cuda.cpp Mon Oct 16 06:31:30 2017 @@ -87,8 +87,7 @@ CudaInstallationDetector::CudaInstallati LibDevicePath = InstallPath + "/nvvm/libdevice"; auto &FS = D.getVFS(); -if (!(FS.exists(IncludePath) && FS.exists(BinPath) && - FS.exists(LibDevicePath))) +if (!(FS.exists(IncludePath) && FS.exists(BinPath))) continue; // On Linux, we have both lib and lib64 directories, and we need to choose @@ -167,17 +166,9 @@ CudaInstallationDetector::CudaInstallati } } -// This code prevents IsValid from being set when -// no libdevice has been found. -bool allEmpty = true; -std::string LibDeviceFile; -for (auto key : LibDeviceMap.keys()) { - LibDeviceFile = LibDeviceMap.lookup(key); - if (!LibDeviceFile.empty()) -allEmpty = false; -} - -if (allEmpty) +// Check that we have found at least one libdevice that we can link in if +// -nocudalib hasn't been specified. +if (LibDeviceMap.empty() && !Args.hasArg(options::OPT_nocudalib)) continue; IsValid = true; Added: cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep?rev=315902&view=auto == (empty) Added: cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep?rev=315902&view=auto == (empty) Added: cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep?rev=315902&view=auto == (empty) Added: cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep?rev=315902&view=auto == (empty) Modified: cfe/trunk/test/Driver/cuda-detect.cu URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cuda-detect.cu?rev=315902&r1=315901&r2=315902&view=diff == --- cfe/trunk/test/Driver/cuda-detect.cu (original) +++ cfe/trunk/test/Driver/cuda-detect.cu Mon Oct 16 06:31:30 2017 @@ -2,7 +2,7 @@ // REQUIRES: x86-registered-target // REQUIRES: nvptx-registered-target // -// # Check that we properly detect CUDA installation. +// Check that we properly detect CUDA installation. // RUN: %clang -v --target=i386-unknown-linux \ // RUN: --sysroot=%S/no-cuda-there 2>&1 | FileCheck %s -check-prefix NOCUDA // RUN: %clang -v --target=i386-apple-macosx \ @@ -18,6 +18,19 @@ // RUN: %clang -v --target=i386-apple-macosx \ // RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 | FileCheck %s +// Check that we don't find a CUDA installation without libdevice ... +// RUN: %clang -v --target=i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdev
[PATCH] D38901: [CUDA] Require libdevice only if needed
This revision was automatically updated to reflect the committed changes. Closed by commit rL315902: [CUDA] Require libdevice only if needed (authored by Hahnfeld). Changed prior to commit: https://reviews.llvm.org/D38901?vs=118969&id=119149#toc Repository: rL LLVM https://reviews.llvm.org/D38901 Files: cfe/trunk/lib/Driver/ToolChains/Cuda.cpp cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/.keep cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/include/.keep cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib/.keep cfe/trunk/test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/lib64/.keep cfe/trunk/test/Driver/cuda-detect.cu Index: cfe/trunk/test/Driver/cuda-detect.cu === --- cfe/trunk/test/Driver/cuda-detect.cu +++ cfe/trunk/test/Driver/cuda-detect.cu @@ -2,7 +2,7 @@ // REQUIRES: x86-registered-target // REQUIRES: nvptx-registered-target // -// # Check that we properly detect CUDA installation. +// Check that we properly detect CUDA installation. // RUN: %clang -v --target=i386-unknown-linux \ // RUN: --sysroot=%S/no-cuda-there 2>&1 | FileCheck %s -check-prefix NOCUDA // RUN: %clang -v --target=i386-apple-macosx \ @@ -18,6 +18,19 @@ // RUN: %clang -v --target=i386-apple-macosx \ // RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 | FileCheck %s +// Check that we don't find a CUDA installation without libdevice ... +// RUN: %clang -v --target=i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NOCUDA +// RUN: %clang -v --target=i386-apple-macosx \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NOCUDA + +// ... unless the user doesn't need libdevice +// RUN: %clang -v --target=i386-unknown-linux -nocudalib \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE +// RUN: %clang -v --target=i386-apple-macosx -nocudalib \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE + + // Make sure we map libdevice bitcode files to proper GPUs. These // tests use Inputs/CUDA_80 which has full set of libdevice files. // However, libdevice mapping only matches CUDA-7.x at the moment. @@ -112,6 +125,7 @@ // RUN: | FileCheck %s --check-prefix CHECK-CXXINCLUDE // CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda +// NO-LIBDEVICE: Found CUDA installation: {{.*}}/Inputs/CUDA-nolibdevice/usr/local/cuda // NOCUDA-NOT: Found CUDA installation: // MISSINGLIBDEVICE: error: cannot find libdevice for sm_20. Index: cfe/trunk/lib/Driver/ToolChains/Cuda.cpp === --- cfe/trunk/lib/Driver/ToolChains/Cuda.cpp +++ cfe/trunk/lib/Driver/ToolChains/Cuda.cpp @@ -87,8 +87,7 @@ LibDevicePath = InstallPath + "/nvvm/libdevice"; auto &FS = D.getVFS(); -if (!(FS.exists(IncludePath) && FS.exists(BinPath) && - FS.exists(LibDevicePath))) +if (!(FS.exists(IncludePath) && FS.exists(BinPath))) continue; // On Linux, we have both lib and lib64 directories, and we need to choose @@ -167,17 +166,9 @@ } } -// This code prevents IsValid from being set when -// no libdevice has been found. -bool allEmpty = true; -std::string LibDeviceFile; -for (auto key : LibDeviceMap.keys()) { - LibDeviceFile = LibDeviceMap.lookup(key); - if (!LibDeviceFile.empty()) -allEmpty = false; -} - -if (allEmpty) +// Check that we have found at least one libdevice that we can link in if +// -nocudalib hasn't been specified. +if (LibDeviceMap.empty() && !Args.hasArg(options::OPT_nocudalib)) continue; IsValid = true; Index: cfe/trunk/test/Driver/cuda-detect.cu === --- cfe/trunk/test/Driver/cuda-detect.cu +++ cfe/trunk/test/Driver/cuda-detect.cu @@ -2,7 +2,7 @@ // REQUIRES: x86-registered-target // REQUIRES: nvptx-registered-target // -// # Check that we properly detect CUDA installation. +// Check that we properly detect CUDA installation. // RUN: %clang -v --target=i386-unknown-linux \ // RUN: --sysroot=%S/no-cuda-there 2>&1 | FileCheck %s -check-prefix NOCUDA // RUN: %clang -v --target=i386-apple-macosx \ @@ -18,6 +18,19 @@ // RUN: %clang -v --target=i386-apple-macosx \ // RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 | FileCheck %s +// Check that we don't find a CUDA installation without libdevice ... +// RUN: %clang -v --target=i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NOCUDA +// RUN: %clang -v --target=i386-apple-macosx \ +// RUN: --sysroot=%S/Inputs/CUDA-nolibdevice 2>&1 | FileCheck %s -check-prefix NOCUDA + +// ... unless the user doesn't need libdevice +// RUN: %clang -v --target=i386-unknown-linux -nocud
[Diffusion] rL302247: Introduce Wzero-as-null-pointer-constant.
lebedev.ri added an edge: D32914: Introduce Wzero-as-null-pointer-constant.. Users: lebedev.ri (Auditor) https://reviews.llvm.org/rL302247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34272: [Tooling] A new framework for executing clang frontend actions.
ioeric updated this revision to Diff 119150. ioeric added a comment. - Add a ExecutionContext class. https://reviews.llvm.org/D34272 Files: include/clang/Tooling/CommonOptionsParser.h include/clang/Tooling/Execution.h include/clang/Tooling/ToolExecutorPluginRegistry.h include/clang/Tooling/Tooling.h lib/Tooling/CMakeLists.txt lib/Tooling/CommonOptionsParser.cpp lib/Tooling/Execution.cpp lib/Tooling/Tooling.cpp unittests/Tooling/ToolingTest.cpp Index: unittests/Tooling/ToolingTest.cpp === --- unittests/Tooling/ToolingTest.cpp +++ unittests/Tooling/ToolingTest.cpp @@ -7,14 +7,18 @@ // //===--===// +#include "gmock/gmock.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Execution.h" +#include "clang/Tooling/ToolExecutorPluginRegistry.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" @@ -60,6 +64,60 @@ private: bool * const FoundTopLevelDecl; }; + +// This traverses the AST and outputs function name as key and "1" as value for +// each function declaration. +class ASTConsumerWithResult +: public ASTConsumer, + public RecursiveASTVisitor { +public: + using ASTVisitor = RecursiveASTVisitor; + + explicit ASTConsumerWithResult(ExecutionContext *Context) : Context(Context) { +assert(Context != nullptr); + } + + void HandleTranslationUnit(clang::ASTContext &Context) override { +TraverseDecl(Context.getTranslationUnitDecl()); + } + + bool TraverseFunctionDecl(clang::FunctionDecl *Decl) { +Context->getToolResults()->addResult(Decl->getNameAsString(), "1"); +return ASTVisitor::TraverseFunctionDecl(Decl); + } + +private: + ExecutionContext *const Context; +}; + +class ReportResultAction : public ASTFrontendAction { +public: + explicit ReportResultAction(ExecutionContext *Context) : Context(Context) { +assert(Context != nullptr); + } + +protected: + std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &compiler, +llvm::StringRef /* dummy */) override { +std::unique_ptr ast_consumer{ +new ASTConsumerWithResult(Context)}; +return ast_consumer; + } + +private: + ExecutionContext *const Context; +}; + +class ReportResultActionFactory : public FrontendActionFactory { +public: + ReportResultActionFactory(ExecutionContext *Context) : Context(Context) {} + FrontendAction *create() override { return new ReportResultAction(Context); } + +private: + ExecutionContext *const Context; +}; + } // end namespace TEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) { @@ -533,5 +591,170 @@ } #endif +inline llvm::Error make_string_error(const llvm::Twine &Message) { + return llvm::make_error(Message, + llvm::inconvertibleErrorCode()); +} + +class TestToolExecutor : public ToolExecutor { +public: + static const char *ExecutorName; + + TestToolExecutor(std::unique_ptr Options) + : OptionsParser(std::move(Options)) {} + + llvm::StringRef getExecutorName() const override { return ExecutorName; } + + llvm::Error execute(const ExecutionConfig &) override { +return llvm::Error::success(); + } + + ExecutionContext *getExecutionContext() override { return nullptr; }; + + llvm::ArrayRef getSourcePaths() const { +return OptionsParser->getSourcePathList(); + } + + void mapVirtualFile(StringRef FilePath, StringRef Content) override { +VFS[FilePath] = Content; + } + +private: + std::unique_ptr OptionsParser; + std::string SourcePaths; + std::map VFS; +}; + +const char *TestToolExecutor::ExecutorName = "TestToolExecutor"; + +class TestToolExecutorPlugin : public ToolExecutorPlugin { +public: + llvm::Expected> + create(int &argc, const char **argv, + llvm::cl::OptionCategory &Category) override { +// FIXME: Using static option here because `opt`s could not be ungirestered +// properly. The static option seems to work fine for now. +static llvm::cl::opt TestExecutor( +"test_executor", llvm::cl::desc("Use TestToolExecutor")); +auto OptionsParser = llvm::make_unique( +argc, argv, Category, llvm::cl::OneOrMore, /*Overview=*/nullptr, +/*ExitOnError=*/false); +if (OptionsParser->hasError()) + return make_string_error("[TestToolExecutorPlugin] " + + OptionsParser->getErrorMessage()); +if (!TestExecutor) + return make_string_error( + "[TestToolExecutorPlugin] --test_executor is not set."); +return llvm::make_unique(std::move(Opti
[PATCH] D38954: [Sema] -Wzero-as-null-pointer-constant: don't warn for system macros.
lebedev.ri created this revision. lebedev.ri added a project: clang. The warning was initially introduced in https://reviews.llvm.org/D32914 by @thakis, and the concerns were raised there, and later in https://reviews.llvm.org/rL302247 and PR33771. I do believe that it makes sense to relax the diagnostic e.g. in this case, when the expression originates from the system header, which can not be modified. This prevents adoption for the diagnostic for codebases which use pthreads (PTHREAD_MUTEX_INITIALIZER), gtest, etc. As @malcolm.parsons suggests, it *may* make sense to also not warn for the template types, but it is not obvious to me how to do that in here. While there, add more tests. Repository: rL LLVM https://reviews.llvm.org/D38954 Files: lib/Sema/Sema.cpp test/SemaCXX/Inputs/warn-zero-nullptr.h test/SemaCXX/warn-zero-nullptr.cpp Index: test/SemaCXX/warn-zero-nullptr.cpp === --- test/SemaCXX/warn-zero-nullptr.cpp +++ test/SemaCXX/warn-zero-nullptr.cpp @@ -1,4 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11 + +#include + +#define MACRO (0) +#define MCRO(x) (x) struct S {}; @@ -15,6 +20,8 @@ void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}} int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}} +void fy(void* v = MACRO); // expected-warning{{zero as null pointer constant}} +void fz(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}} void f0(void* v = 0); // expected-warning{{zero as null pointer constant}} void f1(void* v); @@ -25,3 +32,44 @@ // Warn on these too. Matches gcc and arguably makes sense. void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}} void* pp2 = static_cast(0); // expected-warning{{zero as null pointer constant}} + +template void TmplFunc0(T var) {} +void Func0Test() { + TmplFunc0(0); + TmplFunc0(0); // expected-warning {{zero as null pointer constant}} + TmplFunc0(0); // expected-warning {{zero as null pointer constant}} +} + +// FIXME: this one should *NOT* warn. +template void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} +void FuncTest() { + TmplFunc1(0); + TmplFunc1(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1' required here}} + TmplFunc1(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1' required here}} +} + +template +class TemplateClass0 { + public: + explicit TemplateClass0(T var) {} +}; +void TemplateClass0Test() { + TemplateClass0 a(0); + TemplateClass0 b(0); // expected-warning {{zero as null pointer constant}} + TemplateClass0 c(0); // expected-warning {{zero as null pointer constant}} +} + +template +class TemplateClass1 { + public: +// FIXME: this one should *NOT* warn. + explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} +}; +void IgnoreSubstTemplateType1() { + TemplateClass1 a(1); + TemplateClass1 b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1' required here}} + TemplateClass1 c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1' required here}} +} + +// Do not warn on macros from system headers. +void* sys_init = SYSTEM_MACRO; Index: test/SemaCXX/Inputs/warn-zero-nullptr.h === --- /dev/null +++ test/SemaCXX/Inputs/warn-zero-nullptr.h @@ -0,0 +1 @@ +#define SYSTEM_MACRO (0) Index: lib/Sema/Sema.cpp === --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -440,6 +440,9 @@ return; if (E->getType()->isNullPtrType()) return; + // If the expr was expanded from the macro from system header, don't warn. + if (SourceMgr.isInSystemMacro(E->getLocStart())) +return; // nullptr only exists from C++11 on, so don't warn on its absence earlier. if (!getLangOpts().CPlusPlus11) return; Index: test/SemaCXX/warn-zero-nullptr.cpp === --- test/SemaCXX/warn-zero-nullptr.cpp +++ test/SemaCXX/warn-zero-nullptr.cpp @@ -1,4 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11 + +#include + +#define MACRO (0) +#define MCRO(x) (x) struct S {}; @@ -15,6 +20,8 @@ void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}} int (S::*
[PATCH] D38954: [Sema] -Wzero-as-null-pointer-constant: don't warn for system macros.
thakis added a comment. As said on the bug, this matches gcc's behavior, and with this you won't see this warning for NULL. I don't think this is better. Repository: rL LLVM https://reviews.llvm.org/D38954 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38954: [Sema] -Wzero-as-null-pointer-constant: don't warn for system macros.
lebedev.ri added a comment. In https://reviews.llvm.org/D38954#898586, @thakis wrote: > As said on the bug, this matches gcc's behavior, https://bugs.llvm.org/show_bug.cgi?id=33771#c3 > and with this you won't see this warning for NULL. Finally, an argument that can actually be addressed. > I don't think this is better. Repository: rL LLVM https://reviews.llvm.org/D38954 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38110: [libunwind][MIPS]: Add support for unwinding in O32 and N64 processes.
sdardis added a reviewer: compnerd. sdardis added a subscriber: compnerd. sdardis added a comment. Two last inlined comments and I think that's everything. @compnerd Have I missed anything? Comment at: src/UnwindRegistersSave.S:100 +# +DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) + .set push After looking at another implementation of libunwind and the other platforms that are supported, it seems to me that we need to save all the registers. Comment at: src/UnwindRegistersSave.S:142 +# +DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) + .set push Similarly here as well. https://reviews.llvm.org/D38110 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38954: [Sema] -Wzero-as-null-pointer-constant: don't warn for system macros.
lebedev.ri updated this revision to Diff 119159. lebedev.ri added a comment. Address @thakis review notes: do make sure that we still warn on `NULL`. Any other special macros/cases? Repository: rL LLVM https://reviews.llvm.org/D38954 Files: lib/Sema/Sema.cpp test/SemaCXX/Inputs/warn-zero-nullptr.h test/SemaCXX/warn-zero-nullptr.cpp Index: test/SemaCXX/warn-zero-nullptr.cpp === --- test/SemaCXX/warn-zero-nullptr.cpp +++ test/SemaCXX/warn-zero-nullptr.cpp @@ -1,4 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11 + +#include + +#define MACRO (0) +#define MCRO(x) (x) struct S {}; @@ -15,13 +20,60 @@ void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}} int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}} -void f0(void* v = 0); // expected-warning{{zero as null pointer constant}} -void f1(void* v); +void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}} +void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}} +void f2(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}} +void f3(void* v = MCRO(NULL)); // expected-warning{{zero as null pointer constant}} +void f4(void* v = 0); // expected-warning{{zero as null pointer constant}} +void f5(void* v); void g() { f1(0); // expected-warning{{zero as null pointer constant}} } // Warn on these too. Matches gcc and arguably makes sense. void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}} void* pp2 = static_cast(0); // expected-warning{{zero as null pointer constant}} + +template void TmplFunc0(T var) {} +void Func0Test() { + TmplFunc0(0); + TmplFunc0(0); // expected-warning {{zero as null pointer constant}} + TmplFunc0(0); // expected-warning {{zero as null pointer constant}} +} + +// FIXME: this one should *NOT* warn. +template void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} +void FuncTest() { + TmplFunc1(0); + TmplFunc1(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1' required here}} + TmplFunc1(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1' required here}} +} + +template +class TemplateClass0 { + public: + explicit TemplateClass0(T var) {} +}; +void TemplateClass0Test() { + TemplateClass0 a(0); + TemplateClass0 b(0); // expected-warning {{zero as null pointer constant}} + TemplateClass0 c(0); // expected-warning {{zero as null pointer constant}} +} + +template +class TemplateClass1 { + public: +// FIXME: this one should *NOT* warn. + explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} +}; +void IgnoreSubstTemplateType1() { + TemplateClass1 a(1); + TemplateClass1 b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1' required here}} + TemplateClass1 c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1' required here}} +} + +// Do not warn on *any* other macros from system headers, even if they +// expand to/their expansion contains NULL. +void* sys_init = SYSTEM_MACRO; +void* sys_init2 = OTHER_SYSTEM_MACRO; Index: test/SemaCXX/Inputs/warn-zero-nullptr.h === --- /dev/null +++ test/SemaCXX/Inputs/warn-zero-nullptr.h @@ -0,0 +1,3 @@ +#define NULL (0) +#define SYSTEM_MACRO (0) +#define OTHER_SYSTEM_MACRO (NULL) Index: lib/Sema/Sema.cpp === --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -440,6 +440,14 @@ return; if (E->getType()->isNullPtrType()) return; + + // If it is a macro from system header, and if the macro name is not "NULL", + // do not warn. + SourceLocation MaybeMacroLoc = E->getLocStart(); + if (SourceMgr.isInSystemMacro(E->getLocStart()) && + !findMacroSpelling(MaybeMacroLoc, "NULL")) +return; + // nullptr only exists from C++11 on, so don't warn on its absence earlier. if (!getLangOpts().CPlusPlus11) return; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38943: [ASTImporter] import SubStmt of CaseStmt
xazax.hun added inline comments. Comment at: unittests/AST/ASTImporterTest.cpp:100 + // This might catch other cases. + Imported->dump(ToNothing); r.stahl wrote: > xazax.hun wrote: > > I would elaborate a bit more on the purpose of the code below. > I will need help for that, since I do not have a better rationale myself. My > guess would be that print has different assumptions and error checking than > dump, so executing both increases coverage. So the reason you need this to traverse the AST and crash on the null pointers (when the patch is not applied right?) I think you could comment something like traverse the AST to catch certain bugs like poorly (not) imported subtrees. If we do not want to actually print the whole tree (because it might be noisy) you can also try using a no-op recursive AST visitor. https://reviews.llvm.org/D38943 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D37808: [clang-tidy] Add new hicpp-multiway-paths-covered check for missing branches
JDevlieghere added inline comments. Comment at: clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp:76 + +std::size_t twoPow(std::size_t Bits) { + const std::size_t DiscreteValues = 1ul << Bits; Add a comment describing what this function does. I'd move and rephrase the comment below. Comment at: clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp:98 + // hold. + const std::size_t BitCount = [&T, &Context]() { +if (T->isIntegralType(Context)) Unless you expect a whole bunch of logic to be added here, I'd un-const and initialize BitCount to zero, then just have if-clause reassign it and get rid of the lambda. This will save you a few lines of code and complexity. Comment at: clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp:149 + + llvm::SmallVector DegenerateMsgs = { + "degenerated switch with default label only", If there's only going to be two messages, you could use the ternary operator and save an instantiation of the `SmallVector`. Comment at: clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp:195 + // matcher used for here does not match on degenerate 'switch' + assert(CaseCount > 0 && "Switch stmt without any case found. This case " + "should be excluded by the matcher and is handled " Let's move this to right after where you define CaseCount https://reviews.llvm.org/D37808 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38943: [ASTImporter] import SubStmt of CaseStmt
r.stahl updated this revision to Diff 119162. r.stahl marked 3 inline comments as done. r.stahl added a comment. addressed review comment https://reviews.llvm.org/D38943 Files: lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -97,6 +97,10 @@ llvm::raw_svector_ostream ToNothing(ImportChecker); ToCtx.getTranslationUnitDecl()->print(ToNothing); + // This traverses the AST to catch certain bugs like poorly or not + // implemented subtrees. + Imported->dump(ToNothing); + return Verifier.match(Imported, AMatcher); } @@ -267,6 +271,15 @@ hasUnaryOperand(cxxThisExpr(); } +TEST(ImportExpr, ImportSwitch) { + MatchVerifier Verifier; + EXPECT_TRUE( + testImport("void declToImport() { int b; switch (b) { case 1: break; } }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl(hasBody(compoundStmt( + has(switchStmt(has(compoundStmt(has(caseStmt())); +} + TEST(ImportExpr, ImportStmtExpr) { MatchVerifier Verifier; // NOTE: has() ignores implicit casts, using hasDescendant() to match it Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -3983,12 +3983,16 @@ Expr *ToRHS = Importer.Import(S->getRHS()); if (!ToRHS && S->getRHS()) return nullptr; + Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); + if (!ToSubStmt && S->getSubStmt()) +return nullptr; SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc()); SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc()); SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); - return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS, -ToCaseLoc, ToEllipsisLoc, -ToColonLoc); + CaseStmt *ToStmt = new (Importer.getToContext()) + CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc); + ToStmt->setSubStmt(ToSubStmt); + return ToStmt; } Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) { Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -97,6 +97,10 @@ llvm::raw_svector_ostream ToNothing(ImportChecker); ToCtx.getTranslationUnitDecl()->print(ToNothing); + // This traverses the AST to catch certain bugs like poorly or not + // implemented subtrees. + Imported->dump(ToNothing); + return Verifier.match(Imported, AMatcher); } @@ -267,6 +271,15 @@ hasUnaryOperand(cxxThisExpr(); } +TEST(ImportExpr, ImportSwitch) { + MatchVerifier Verifier; + EXPECT_TRUE( + testImport("void declToImport() { int b; switch (b) { case 1: break; } }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl(hasBody(compoundStmt( + has(switchStmt(has(compoundStmt(has(caseStmt())); +} + TEST(ImportExpr, ImportStmtExpr) { MatchVerifier Verifier; // NOTE: has() ignores implicit casts, using hasDescendant() to match it Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -3983,12 +3983,16 @@ Expr *ToRHS = Importer.Import(S->getRHS()); if (!ToRHS && S->getRHS()) return nullptr; + Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); + if (!ToSubStmt && S->getSubStmt()) +return nullptr; SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc()); SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc()); SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); - return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS, -ToCaseLoc, ToEllipsisLoc, -ToColonLoc); + CaseStmt *ToStmt = new (Importer.getToContext()) + CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc); + ToStmt->setSubStmt(ToSubStmt); + return ToStmt; } Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38943: [ASTImporter] import SubStmt of CaseStmt
r.stahl added a comment. If all is good, I will need someone to commit this for me please. Comment at: unittests/AST/ASTImporterTest.cpp:100 + // This might catch other cases. + Imported->dump(ToNothing); xazax.hun wrote: > r.stahl wrote: > > xazax.hun wrote: > > > I would elaborate a bit more on the purpose of the code below. > > I will need help for that, since I do not have a better rationale myself. > > My guess would be that print has different assumptions and error checking > > than dump, so executing both increases coverage. > So the reason you need this to traverse the AST and crash on the null > pointers (when the patch is not applied right?) > I think you could comment something like traverse the AST to catch certain > bugs like poorly (not) imported subtrees. > If we do not want to actually print the whole tree (because it might be > noisy) you can also try using a no-op recursive AST visitor. Yes, of course this referred to the case when the patch is not applied. There is no noise since the dump is done on a buffer that will be discarded. https://reviews.llvm.org/D38943 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38921: [analyzer] LoopUnrolling: update the matched assignment operators
NoQ added a comment. Neat! Tests? https://reviews.llvm.org/D38921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34272: [Tooling] A new framework for executing clang frontend actions.
arphaman added inline comments. Comment at: include/clang/Tooling/CommonOptionsParser.h:116 + bool HasError; + std::string ErrorMessage; std::unique_ptr Compilations; Would it be better to have an `llvm::Error' instead of the two fields? Comment at: include/clang/Tooling/Execution.h:47 + virtual ~ToolResults() {} + virtual void addResult(llvm::StringRef Key, llvm::StringRef Value) = 0; + virtual std::vector> AllKVResults() = 0; You don't need to use the `llvm::` prefix for `StringRef`. Comment at: include/clang/Tooling/Execution.h:76 +private: + ToolResults *Results; +}; Why not `unique_ptr`/`shared_ptr`? Who owns the results? Comment at: include/clang/Tooling/Execution.h:134 + +/// \brief A stand alone executor that runs FrontendActions on a given set of +/// TUs in sequence. Standalone is one word. Comment at: include/clang/Tooling/Execution.h:136 +/// TUs in sequence. +class StandaloneToolExecutor : public ToolExecutor { +public: Maybe this class and `InMemoryToolResults` should be in a separate header? https://reviews.llvm.org/D34272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315915 - [Bitfield] Add an option to access bitfield in a fine-grained manner.
Author: wmi Date: Mon Oct 16 09:50:27 2017 New Revision: 315915 URL: http://llvm.org/viewvc/llvm-project?rev=315915&view=rev Log: [Bitfield] Add an option to access bitfield in a fine-grained manner. Currently all the consecutive bitfields are wrapped as a large integer unless there is unamed zero sized bitfield in between. The patch provides an alternative manner which makes the bitfield to be accessed as separate memory location if it has legal integer width and is naturally aligned. Such separate bitfield may split the original consecutive bitfields into subgroups of consecutive bitfields, and each subgroup will be wrapped as an integer. Now This is all controlled by an option -ffine-grained-bitfield-accesses. The alternative of bitfield access manner can improve the access efficiency of those bitfields with legal width and being aligned, but may reduce the chance of load/store combining of other bitfields, so it depends on how the bitfields are defined and actually accessed to choose when to use the option. For now the option is off by default. Differential revision: https://reviews.llvm.org/D36562 Added: cfe/trunk/test/CodeGenCXX/finegrain-bitfield-access.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td cfe/trunk/include/clang/Driver/Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp cfe/trunk/lib/Driver/ToolChains/Clang.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=315915&r1=315914&r2=315915&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Mon Oct 16 09:50:27 2017 @@ -330,4 +330,8 @@ def warn_drv_msvc_not_found : Warning< "unable to find a Visual Studio installation; " "try running Clang from a developer command prompt">, InGroup>; + +def warn_drv_fine_grained_bitfield_accesses_ignored : Warning< + "option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">, + InGroup; } Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=315915&r1=315914&r2=315915&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Mon Oct 16 09:50:27 2017 @@ -1045,6 +1045,13 @@ def fxray_never_instrument : Group, Flags<[CC1Option]>, HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">; +def ffine_grained_bitfield_accesses : Flag<["-"], + "ffine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, + HelpText<"Use separate accesses for bitfields with legal widths and alignments.">; +def fno_fine_grained_bitfield_accesses : Flag<["-"], + "fno-fine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, + HelpText<"Use large-integer access for consecutive bitfield runs.">; + def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group; def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group; Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=315915&r1=315914&r2=315915&view=diff == --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original) +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Mon Oct 16 09:50:27 2017 @@ -179,6 +179,7 @@ CODEGENOPT(SanitizeCoverageStackDepth, 1 CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers. CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float. +CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses. CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers CODEGENOPT(TimePasses, 1, 0) ///< Set when -ftime-report is enabled. Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=315915&r1=315914&r2=315915&view=diff == --- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Mon Oct 16 09:50:27 2017 @@ -403,6 +403,27 @@ CGRecordLowering::acc
[PATCH] D36562: [Bitfield] Make the bitfield a separate location if it has width of legal integer type and its bit offset is naturally aligned for the type
This revision was automatically updated to reflect the committed changes. Closed by commit rL315915: [Bitfield] Add an option to access bitfield in a fine-grained manner. (authored by wmi). Changed prior to commit: https://reviews.llvm.org/D36562?vs=118181&id=119170#toc Repository: rL LLVM https://reviews.llvm.org/D36562 Files: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td cfe/trunk/include/clang/Driver/Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp cfe/trunk/lib/Driver/ToolChains/Clang.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/test/CodeGenCXX/finegrain-bitfield-access.cpp Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1045,6 +1045,13 @@ Group, Flags<[CC1Option]>, HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">; +def ffine_grained_bitfield_accesses : Flag<["-"], + "ffine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, + HelpText<"Use separate accesses for bitfields with legal widths and alignments.">; +def fno_fine_grained_bitfield_accesses : Flag<["-"], + "fno-fine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, + HelpText<"Use large-integer access for consecutive bitfield runs.">; + def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group; def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group; Index: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td @@ -330,4 +330,8 @@ "unable to find a Visual Studio installation; " "try running Clang from a developer command prompt">, InGroup>; + +def warn_drv_fine_grained_bitfield_accesses_ignored : Warning< + "option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">, + InGroup; } Index: cfe/trunk/include/clang/Frontend/CodeGenOptions.def === --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def @@ -179,6 +179,7 @@ CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers. CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float. +CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses. CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers CODEGENOPT(TimePasses, 1, 0) ///< Set when -ftime-report is enabled. Index: cfe/trunk/test/CodeGenCXX/finegrain-bitfield-access.cpp === --- cfe/trunk/test/CodeGenCXX/finegrain-bitfield-access.cpp +++ cfe/trunk/test/CodeGenCXX/finegrain-bitfield-access.cpp @@ -0,0 +1,162 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -fsanitize=address -o - %s | FileCheck %s --check-prefix=SANITIZE +// Check -fsplit-bitfields will be ignored since sanitizer is enabled. + +struct S1 { + unsigned f1:2; + unsigned f2:6; + unsigned f3:8; + unsigned f4:4; + unsigned f5:8; +}; + +S1 a1; +unsigned read8_1() { + // CHECK-LABEL: @_Z7read8_1v + // CHECK: %bf.load = load i8, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1 + // CHECK-NEXT: %bf.cast = zext i8 %bf.load to i32 + // CHECK-NEXT: ret i32 %bf.cast + // SANITIZE-LABEL: @_Z7read8_1v + // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4 + // SANITIZE: %bf.lshr = lshr i32 %bf.load, 8 + // SANITIZE: %bf.clear = and i32 %bf.lshr, 255 + // SANITIZE: ret i32 %bf.clear + return a1.f3; +} +void write8_1() { + // CHECK-LABEL: @_Z8write8_1v + // CHECK: store i8 3, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1 + // CHECK-NEXT: ret void + // SANITIZE-LABEL: @_Z8write8_1v + // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4 + // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -65281 + // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 768 + // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4 + // SANITIZE-NEXT: ret void + a1.f3 = 3; +} + +unsigned read8_2() { + // CHECK-LABEL: @_Z7read8_2v + // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S
Re: [libcxx] r315874 - Silence clang's -Wtautological-constant-compare in last_write_time.pass.cpp
Would it be better/possible to improve the warning to not have this false positive, rather than suppressing it? On Sun, Oct 15, 2017 at 1:12 PM Roman Lebedev via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: lebedevri > Date: Sun Oct 15 13:12:42 2017 > New Revision: 315874 > > URL: http://llvm.org/viewvc/llvm-project?rev=315874&view=rev > Log: > Silence clang's -Wtautological-constant-compare in last_write_time.pass.cpp > > Previously this broke the builders, when D38101 was committed. > Silence the warning so that it can be re-landed. > > Modified: > > libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp > > Modified: > libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp?rev=315874&r1=315873&r2=315874&view=diff > > == > --- > libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp > (original) > +++ > libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp > Sun Oct 15 13:12:42 2017 > @@ -88,6 +88,13 @@ bool TestSupportsNegativeTimes() { > return !ec && new_write_time <= -5; > } > > +// In some configurations, the comparison is tautological and the test is > valid. > +// We disable the warning so that we can actually test it regardless. > +#if defined(__clang__) > +#pragma clang diagnostic push > +#pragma clang diagnostic ignored "-Wtautological-constant-compare" > +#endif > + > bool TestSupportsMaxTime() { > using namespace std::chrono; > using Lim = std::numeric_limits; > @@ -106,11 +113,22 @@ bool TestSupportsMaxTime() { > return !ec && new_write_time > max_sec - 1; > } > > +#if defined(__clang__) > +#pragma clang diagnostic pop > +#endif > + > static const bool SupportsNegativeTimes = TestSupportsNegativeTimes(); > static const bool SupportsMaxTime = TestSupportsMaxTime(); > > } // end namespace > > +// In some configurations, the comparison is tautological and the test is > valid. > +// We disable the warning so that we can actually test it regardless. > +#if defined(__clang__) > +#pragma clang diagnostic push > +#pragma clang diagnostic ignored "-Wtautological-constant-compare" > +#endif > + > // Check if a time point is representable on a given filesystem. Check > that: > // (A) 'tp' is representable as a time_t > // (B) 'tp' is non-negative or the filesystem supports negative times. > @@ -127,6 +145,10 @@ inline bool TimeIsRepresentableByFilesys > return true; > } > > +#if defined(__clang__) > +#pragma clang diagnostic pop > +#endif > + > TEST_SUITE(exists_test_suite) > > TEST_CASE(signature_test) > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r315755 - Fix -Woverloaded-virtual warning in clang-refactor
Is there a test that could be added to cover this new code? On Fri, Oct 13, 2017 at 2:15 PM Alex Lorenz via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: arphaman > Date: Fri Oct 13 14:15:25 2017 > New Revision: 315755 > > URL: http://llvm.org/viewvc/llvm-project?rev=315755&view=rev > Log: > Fix -Woverloaded-virtual warning in clang-refactor > > Modified: > cfe/trunk/tools/clang-refactor/ClangRefactor.cpp > > Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-refactor/ClangRefactor.cpp?rev=315755&r1=315754&r2=315755&view=diff > > == > --- cfe/trunk/tools/clang-refactor/ClangRefactor.cpp (original) > +++ cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Fri Oct 13 14:15:25 > 2017 > @@ -314,6 +314,10 @@ public: > SourceChanges.insert(SourceChanges.begin(), Changes.begin(), > Changes.end()); >} > > + void handle(SymbolOccurrences Occurrences) override { > +RefactoringResultConsumer::handle(std::move(Occurrences)); > + } > + >const AtomicChanges &getSourceChanges() const { return SourceChanges; } > > private: > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [clang-tools-extra] r315323 - [clangd] Added forgotten return in UniqueFunction.
Is there missing test coverage for this? On Tue, Oct 10, 2017 at 9:12 AM Ilya Biryukov via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: ibiryukov > Date: Tue Oct 10 09:12:47 2017 > New Revision: 315323 > > URL: http://llvm.org/viewvc/llvm-project?rev=315323&view=rev > Log: > [clangd] Added forgotten return in UniqueFunction. > > This hasn't bitten us because we only used functions returning > 'void'. > > Modified: > clang-tools-extra/trunk/clangd/Function.h > > Modified: clang-tools-extra/trunk/clangd/Function.h > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Function.h?rev=315323&r1=315322&r2=315323&view=diff > > == > --- clang-tools-extra/trunk/clangd/Function.h (original) > +++ clang-tools-extra/trunk/clangd/Function.h Tue Oct 10 09:12:47 2017 > @@ -46,7 +46,7 @@ public: > >Ret operator()(Args... As) { > assert(CallablePtr); > -CallablePtr->Call(std::forward(As)...); > +return CallablePtr->Call(std::forward(As)...); >} > > private: > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libcxx] r315874 - Silence clang's -Wtautological-constant-compare in last_write_time.pass.cpp
On Mon, Oct 16, 2017 at 8:09 PM, David Blaikie wrote: > Would it be better/possible to improve the warning to not have this false > positive, rather than suppressing it? I am willing to look into it, once there is a clear minimal test-case, that does not boil down to completely ignoring std::numeric_limits<>. Right now, sadly, i do not see any simple false-positive here. Roman. > On Sun, Oct 15, 2017 at 1:12 PM Roman Lebedev via cfe-commits > wrote: >> >> Author: lebedevri >> Date: Sun Oct 15 13:12:42 2017 >> New Revision: 315874 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=315874&view=rev >> Log: >> Silence clang's -Wtautological-constant-compare in >> last_write_time.pass.cpp >> >> Previously this broke the builders, when D38101 was committed. >> Silence the warning so that it can be re-landed. >> >> Modified: >> >> libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp >> >> Modified: >> libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp?rev=315874&r1=315873&r2=315874&view=diff >> >> == >> --- >> libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp >> (original) >> +++ >> libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp >> Sun Oct 15 13:12:42 2017 >> @@ -88,6 +88,13 @@ bool TestSupportsNegativeTimes() { >> return !ec && new_write_time <= -5; >> } >> >> +// In some configurations, the comparison is tautological and the test is >> valid. >> +// We disable the warning so that we can actually test it regardless. >> +#if defined(__clang__) >> +#pragma clang diagnostic push >> +#pragma clang diagnostic ignored "-Wtautological-constant-compare" >> +#endif >> + >> bool TestSupportsMaxTime() { >> using namespace std::chrono; >> using Lim = std::numeric_limits; >> @@ -106,11 +113,22 @@ bool TestSupportsMaxTime() { >> return !ec && new_write_time > max_sec - 1; >> } >> >> +#if defined(__clang__) >> +#pragma clang diagnostic pop >> +#endif >> + >> static const bool SupportsNegativeTimes = TestSupportsNegativeTimes(); >> static const bool SupportsMaxTime = TestSupportsMaxTime(); >> >> } // end namespace >> >> +// In some configurations, the comparison is tautological and the test is >> valid. >> +// We disable the warning so that we can actually test it regardless. >> +#if defined(__clang__) >> +#pragma clang diagnostic push >> +#pragma clang diagnostic ignored "-Wtautological-constant-compare" >> +#endif >> + >> // Check if a time point is representable on a given filesystem. Check >> that: >> // (A) 'tp' is representable as a time_t >> // (B) 'tp' is non-negative or the filesystem supports negative times. >> @@ -127,6 +145,10 @@ inline bool TimeIsRepresentableByFilesys >> return true; >> } >> >> +#if defined(__clang__) >> +#pragma clang diagnostic pop >> +#endif >> + >> TEST_SUITE(exists_test_suite) >> >> TEST_CASE(signature_test) >> >> >> ___ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r315755 - Fix -Woverloaded-virtual warning in clang-refactor
At the moment this method override is not used by the clang-refactor tool, so I don't think I can add a test for it. On 16 October 2017 at 10:11, David Blaikie wrote: > Is there a test that could be added to cover this new code? > > On Fri, Oct 13, 2017 at 2:15 PM Alex Lorenz via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: arphaman >> Date: Fri Oct 13 14:15:25 2017 >> New Revision: 315755 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=315755&view=rev >> Log: >> Fix -Woverloaded-virtual warning in clang-refactor >> >> Modified: >> cfe/trunk/tools/clang-refactor/ClangRefactor.cpp >> >> Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang- >> refactor/ClangRefactor.cpp?rev=315755&r1=315754&r2=315755&view=diff >> >> == >> --- cfe/trunk/tools/clang-refactor/ClangRefactor.cpp (original) >> +++ cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Fri Oct 13 14:15:25 >> 2017 >> @@ -314,6 +314,10 @@ public: >> SourceChanges.insert(SourceChanges.begin(), Changes.begin(), >> Changes.end()); >>} >> >> + void handle(SymbolOccurrences Occurrences) override { >> +RefactoringResultConsumer::handle(std::move(Occurrences)); >> + } >> + >>const AtomicChanges &getSourceChanges() const { return SourceChanges; } >> >> private: >> >> >> ___ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315918 - Recommit r315738 "[clang-refactor] Apply source replacements"
Author: arphaman Date: Mon Oct 16 10:31:16 2017 New Revision: 315918 URL: http://llvm.org/viewvc/llvm-project?rev=315918&view=rev Log: Recommit r315738 "[clang-refactor] Apply source replacements" The fixed commit ensures that ParsedSourceRange works correctly with Windows paths. Original message: This commit actually brings clang-refactor to a usable state as it can now apply the refactoring changes to source files. The -selection option is now also fully supported. Differential Revision: https://reviews.llvm.org/D38402 Added: cfe/trunk/test/Refactor/tool-apply-replacements.cpp cfe/trunk/test/Refactor/tool-selection-option.c cfe/trunk/unittests/Frontend/ParsedSourceLocationTest.cpp Modified: cfe/trunk/include/clang/Frontend/CommandLineSourceLoc.h cfe/trunk/tools/clang-refactor/ClangRefactor.cpp cfe/trunk/unittests/Frontend/CMakeLists.txt Modified: cfe/trunk/include/clang/Frontend/CommandLineSourceLoc.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CommandLineSourceLoc.h?rev=315918&r1=315917&r2=315918&view=diff == --- cfe/trunk/include/clang/Frontend/CommandLineSourceLoc.h (original) +++ cfe/trunk/include/clang/Frontend/CommandLineSourceLoc.h Mon Oct 16 10:31:16 2017 @@ -51,6 +51,52 @@ public: } }; +/// A source range that has been parsed on the command line. +struct ParsedSourceRange { + std::string FileName; + /// The starting location of the range. The first element is the line and + /// the second element is the column. + std::pair Begin; + /// The ending location of the range. The first element is the line and the + /// second element is the column. + std::pair End; + + /// Returns a parsed source range from a string or None if the string is + /// invalid. + /// + /// These source string has the following format: + /// + /// file:start_line:start_column[-end_line:end_column] + /// + /// If the end line and column are omitted, the starting line and columns + /// are used as the end values. + static Optional fromString(StringRef Str) { +std::pair RangeSplit = Str.rsplit('-'); +unsigned EndLine, EndColumn; +bool HasEndLoc = false; +if (!RangeSplit.second.empty()) { + std::pair Split = RangeSplit.second.rsplit(':'); + if (Split.first.getAsInteger(10, EndLine) || + Split.second.getAsInteger(10, EndColumn)) { +// The string does not end in end_line:end_column, so the '-' +// probably belongs to the filename which menas the whole +// string should be parsed. +RangeSplit.first = Str; + } else +HasEndLoc = true; +} +auto Begin = ParsedSourceLocation::FromString(RangeSplit.first); +if (Begin.FileName.empty()) + return None; +if (!HasEndLoc) { + EndLine = Begin.Line; + EndColumn = Begin.Column; +} +return ParsedSourceRange{std::move(Begin.FileName), + {Begin.Line, Begin.Column}, + {EndLine, EndColumn}}; + } +}; } namespace llvm { Added: cfe/trunk/test/Refactor/tool-apply-replacements.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Refactor/tool-apply-replacements.cpp?rev=315918&view=auto == --- cfe/trunk/test/Refactor/tool-apply-replacements.cpp (added) +++ cfe/trunk/test/Refactor/tool-apply-replacements.cpp Mon Oct 16 10:31:16 2017 @@ -0,0 +1,11 @@ +// RUN: rm -f %t.cp.cpp +// RUN: cp %s %t.cp.cpp +// RUN: clang-refactor local-rename -selection=%t.cp.cpp:9:7 -new-name=test %t.cp.cpp -- +// RUN: grep -v CHECK %t.cp.cpp | FileCheck %t.cp.cpp +// RUN: cp %s %t.cp.cpp +// RUN: clang-refactor local-rename -selection=%t.cp.cpp:9:7-9:15 -new-name=test %t.cp.cpp -- +// RUN: grep -v CHECK %t.cp.cpp | FileCheck %t.cp.cpp + +class RenameMe { +// CHECK: class test { +}; Added: cfe/trunk/test/Refactor/tool-selection-option.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Refactor/tool-selection-option.c?rev=315918&view=auto == --- cfe/trunk/test/Refactor/tool-selection-option.c (added) +++ cfe/trunk/test/Refactor/tool-selection-option.c Mon Oct 16 10:31:16 2017 @@ -0,0 +1,15 @@ +// RUN: rm -f %t.cp.c +// RUN: cp %s %t.cp.c +// RUN: clang-refactor local-rename -selection=%t.cp.c:6:5 -new-name=test -v %t.cp.c -- | FileCheck --check-prefix=CHECK1 %s +// RUN: clang-refactor local-rename -selection=%t.cp.c:6:5-6:9 -new-name=test -v %t.cp.c -- | FileCheck --check-prefix=CHECK2 %s + +int test; + +// CHECK1: invoking action 'local-rename': +// CHECK1-NEXT: -selection={{.*}}.cp.c:6:5 -> {{.*}}.cp.c:6:5 + +// CHECK2: invoking action 'local-rename': +// CHECK2-NEXT: -selection={{.*}}.cp.c:6:5 -> {{.*}}.cp.c:6:9 + +// RUN: not clang-refactor local-rename -selection=%s:6:5 -new-name=test -v %t.cp.c -- 2>&1 | FileCheck --chec
Re: r315755 - Fix -Woverloaded-virtual warning in clang-refactor
Generally it's preferably to avoid adding dead code (partly for this reason - it's hard to track when it gets used and ensure it's appropriately tested) could the member function's body be replaced with llvm_unreachable for now, then? On Mon, Oct 16, 2017 at 10:27 AM Alex L wrote: > At the moment this method override is not used by the clang-refactor tool, > so I don't think I can add a test for it. > > On 16 October 2017 at 10:11, David Blaikie wrote: > >> Is there a test that could be added to cover this new code? >> >> On Fri, Oct 13, 2017 at 2:15 PM Alex Lorenz via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: arphaman >>> Date: Fri Oct 13 14:15:25 2017 >>> New Revision: 315755 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=315755&view=rev >>> Log: >>> Fix -Woverloaded-virtual warning in clang-refactor >>> >>> Modified: >>> cfe/trunk/tools/clang-refactor/ClangRefactor.cpp >>> >>> Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-refactor/ClangRefactor.cpp?rev=315755&r1=315754&r2=315755&view=diff >>> >>> == >>> --- cfe/trunk/tools/clang-refactor/ClangRefactor.cpp (original) >>> +++ cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Fri Oct 13 14:15:25 >>> 2017 >>> @@ -314,6 +314,10 @@ public: >>> SourceChanges.insert(SourceChanges.begin(), Changes.begin(), >>> Changes.end()); >>>} >>> >>> + void handle(SymbolOccurrences Occurrences) override { >>> +RefactoringResultConsumer::handle(std::move(Occurrences)); >>> + } >>> + >>>const AtomicChanges &getSourceChanges() const { return SourceChanges; >>> } >>> >>> private: >>> >>> >>> ___ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r315755 - Fix -Woverloaded-virtual warning in clang-refactor
That's a good idea! I'll commit an llvm_unreachable fix for this override then. On 16 October 2017 at 10:32, David Blaikie wrote: > Generally it's preferably to avoid adding dead code (partly for this > reason - it's hard to track when it gets used and ensure it's appropriately > tested) could the member function's body be replaced with llvm_unreachable > for now, then? > > On Mon, Oct 16, 2017 at 10:27 AM Alex L wrote: > >> At the moment this method override is not used by the clang-refactor >> tool, so I don't think I can add a test for it. >> >> On 16 October 2017 at 10:11, David Blaikie wrote: >> >>> Is there a test that could be added to cover this new code? >>> >>> On Fri, Oct 13, 2017 at 2:15 PM Alex Lorenz via cfe-commits < >>> cfe-commits@lists.llvm.org> wrote: >>> Author: arphaman Date: Fri Oct 13 14:15:25 2017 New Revision: 315755 URL: http://llvm.org/viewvc/llvm-project?rev=315755&view=rev Log: Fix -Woverloaded-virtual warning in clang-refactor Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang- refactor/ClangRefactor.cpp?rev=315755&r1=315754&r2=315755&view=diff == --- cfe/trunk/tools/clang-refactor/ClangRefactor.cpp (original) +++ cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Fri Oct 13 14:15:25 2017 @@ -314,6 +314,10 @@ public: SourceChanges.insert(SourceChanges.begin(), Changes.begin(), Changes.end()); } + void handle(SymbolOccurrences Occurrences) override { +RefactoringResultConsumer::handle(std::move(Occurrences)); + } + const AtomicChanges &getSourceChanges() const { return SourceChanges; } private: ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38857: [OpenCL] Improve printing and semantic check related to implicit addr space
yaxunl marked an inline comment as done. yaxunl added a comment. In https://reviews.llvm.org/D38857#896994, @Anastasia wrote: > LGTM! Thanks! > > Can we close https://bugs.llvm.org/show_bug.cgi?id=33418 after this commit? Will do. Comment at: test/SemaOpenCL/null_literal.cl:38 -#ifdef CL20 -// Accept explicitly pointer to generic address space in OpenCL v2.0. -global int* ptr5 = (generic void*)0; -#endif - -global int* ptr6 = (local void*)0; // expected-error{{initializing '__global int *' with an expression of type '__local void *' changes address space of pointer}} + global int *g7 = (global void*)(generic void *)0; + constant int *c7 = (constant void*)(generic void *)0; //expected-error{{casting '__generic void *' to type '__constant void *' changes address space of pointer}} Anastasia wrote: > Does this extra cast test anything we already miss to test? Yes. It tests a generic pointer of zero value can be explicitly casted to a global pointer. This should be true for any generic pointer, however since pointers with zero value have special handling, we want to make sure this still works. https://reviews.llvm.org/D38857 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315921 - Do not link clang_rt.cfi on Android.
Author: eugenis Date: Mon Oct 16 11:02:57 2017 New Revision: 315921 URL: http://llvm.org/viewvc/llvm-project?rev=315921&view=rev Log: Do not link clang_rt.cfi on Android. Summary: The OS provides cross-dso CFI support starting with Android O. Trapping mode does not require any runtime at all, and diagnostic mode requires just ubsan-standalone. Reviewers: pcc Subscribers: srhines, cfe-commits Differential Revision: https://reviews.llvm.org/D38908 Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/test/Driver/sanitizer-ld.c Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=315921&r1=315920&r2=315921&view=diff == --- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original) +++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Mon Oct 16 11:02:57 2017 @@ -44,6 +44,8 @@ class SanitizerArgs { bool TsanFuncEntryExit = true; bool TsanAtomics = true; bool MinimalRuntime = false; + // True if cross-dso CFI support if provided by the system (i.e. Android). + bool ImplicitCfiRuntime = false; public: /// Parses the sanitizer arguments from an argument list. Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=315921&r1=315920&r2=315921&view=diff == --- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original) +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Mon Oct 16 11:02:57 2017 @@ -171,19 +171,23 @@ static SanitizerMask parseSanitizeTrapAr } bool SanitizerArgs::needsUbsanRt() const { - return ((Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || - CoverageFeatures) && - !Sanitizers.has(Address) && !Sanitizers.has(Memory) && - !Sanitizers.has(Thread) && !Sanitizers.has(DataFlow) && - !Sanitizers.has(Leak) && !CfiCrossDso; + // All of these include ubsan. + if (needsAsanRt() || needsMsanRt() || needsTsanRt() || needsDfsanRt() || + needsLsanRt() || needsCfiDiagRt()) +return false; + + return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || + CoverageFeatures; } bool SanitizerArgs::needsCfiRt() const { - return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso; + return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && + !ImplicitCfiRuntime; } bool SanitizerArgs::needsCfiDiagRt() const { - return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso; + return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && + !ImplicitCfiRuntime; } bool SanitizerArgs::requiresPIE() const { @@ -615,6 +619,8 @@ SanitizerArgs::SanitizerArgs(const ToolC TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() || TC.getTriple().isOSDarwin()); + ImplicitCfiRuntime = TC.getTriple().isAndroid(); + if (AllAddedKinds & Address) { NeedPIE |= TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia(); if (Arg *A = Modified: cfe/trunk/test/Driver/sanitizer-ld.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/sanitizer-ld.c?rev=315921&r1=315920&r2=315921&view=diff == --- cfe/trunk/test/Driver/sanitizer-ld.c (original) +++ cfe/trunk/test/Driver/sanitizer-ld.c Mon Oct 16 11:02:57 2017 @@ -508,6 +508,24 @@ // CHECK-CFI-CROSS-DSO-DIAG-LINUX: "-whole-archive" "{{[^"]*}}libclang_rt.cfi_diag-x86_64.a" "-no-whole-archive" // CHECK-CFI-CROSS-DSO-DIAG-LINUX: -export-dynamic +// Cross-DSO CFI on Android does not link runtime libraries. +// RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \ +// RUN: -target aarch64-linux-android -fuse-ld=ld \ +// RUN: --sysroot=%S/Inputs/basic_android_tree \ +// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-ANDROID %s +// CHECK-CFI-CROSS-DSO-ANDROID: "{{.*}}ld{{(.exe)?}}" +// CHECK-CFI-CROSS-DSO-ANDROID-NOT: libclang_rt. + +// Cross-DSO CFI with diagnostics on Android links just the UBSAN runtime. +// RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \ +// RUN: -fno-sanitize-trap=cfi -fsanitize-recover=cfi \ +// RUN: -target aarch64-linux-android -fuse-ld=ld \ +// RUN: --sysroot=%S/Inputs/basic_android_tree \ +// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-DIAG-ANDROID %s +// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{.*}}ld{{(.exe)?}}" +// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{[^"]*}}libclang_rt.ubsan_standalone-aarch64-android.so" +// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "-export-dynamic-symbol=__cfi_check" + // RUN: %clangxx -fsanitize=address %s -### -o %t.o 2>&1 \ // RUN: -mmacosx-version-min=10.6 \ // RUN: -target x86_64
[PATCH] D38908: Do not link clang_rt.cfi on Android.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315921: Do not link clang_rt.cfi on Android. (authored by eugenis). Changed prior to commit: https://reviews.llvm.org/D38908?vs=118986&id=119180#toc Repository: rL LLVM https://reviews.llvm.org/D38908 Files: cfe/trunk/include/clang/Driver/SanitizerArgs.h cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/test/Driver/sanitizer-ld.c Index: cfe/trunk/include/clang/Driver/SanitizerArgs.h === --- cfe/trunk/include/clang/Driver/SanitizerArgs.h +++ cfe/trunk/include/clang/Driver/SanitizerArgs.h @@ -44,6 +44,8 @@ bool TsanFuncEntryExit = true; bool TsanAtomics = true; bool MinimalRuntime = false; + // True if cross-dso CFI support if provided by the system (i.e. Android). + bool ImplicitCfiRuntime = false; public: /// Parses the sanitizer arguments from an argument list. Index: cfe/trunk/test/Driver/sanitizer-ld.c === --- cfe/trunk/test/Driver/sanitizer-ld.c +++ cfe/trunk/test/Driver/sanitizer-ld.c @@ -508,6 +508,24 @@ // CHECK-CFI-CROSS-DSO-DIAG-LINUX: "-whole-archive" "{{[^"]*}}libclang_rt.cfi_diag-x86_64.a" "-no-whole-archive" // CHECK-CFI-CROSS-DSO-DIAG-LINUX: -export-dynamic +// Cross-DSO CFI on Android does not link runtime libraries. +// RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \ +// RUN: -target aarch64-linux-android -fuse-ld=ld \ +// RUN: --sysroot=%S/Inputs/basic_android_tree \ +// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-ANDROID %s +// CHECK-CFI-CROSS-DSO-ANDROID: "{{.*}}ld{{(.exe)?}}" +// CHECK-CFI-CROSS-DSO-ANDROID-NOT: libclang_rt. + +// Cross-DSO CFI with diagnostics on Android links just the UBSAN runtime. +// RUN: %clang -fsanitize=cfi -fsanitize-cfi-cross-dso %s -### -o %t.o 2>&1 \ +// RUN: -fno-sanitize-trap=cfi -fsanitize-recover=cfi \ +// RUN: -target aarch64-linux-android -fuse-ld=ld \ +// RUN: --sysroot=%S/Inputs/basic_android_tree \ +// RUN: | FileCheck --check-prefix=CHECK-CFI-CROSS-DSO-DIAG-ANDROID %s +// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{.*}}ld{{(.exe)?}}" +// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "{{[^"]*}}libclang_rt.ubsan_standalone-aarch64-android.so" +// CHECK-CFI-CROSS-DSO-DIAG-ANDROID: "-export-dynamic-symbol=__cfi_check" + // RUN: %clangxx -fsanitize=address %s -### -o %t.o 2>&1 \ // RUN: -mmacosx-version-min=10.6 \ // RUN: -target x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \ @@ -596,26 +614,6 @@ // CHECK-SAFESTACK-ANDROID-AARCH64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-SAFESTACK-ANDROID-AARCH64-NOT: libclang_rt.safestack -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=cfi \ -// RUN: --sysroot=%S/Inputs/basic_android_tree \ -// RUN: | FileCheck --check-prefix=CHECK-CFI-ANDROID %s -// -// CHECK-CFI-ANDROID: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" -// CHECK-CFI-ANDROID-NOT: libclang_rt.cfi -// CHECK-CFI-ANDROID-NOT: __cfi_check - -// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=cfi \ -// RUN: -fsanitize-cfi-cross-dso \ -// RUN: --sysroot=%S/Inputs/basic_android_tree \ -// RUN: | FileCheck --check-prefix=CHECK-CROSSDSO-CFI-ANDROID %s -// -// CHECK-CROSSDSO-CFI-ANDROID: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" -// CHECK-CROSSDSO-CFI-ANDROID-NOT: libclang_rt.cfi -// CHECK-CROSSDSO-CFI-ANDROID: -export-dynamic-symbol=__cfi_check -// CHECK-CROSSDSO-CFI-ANDROID-NOT: libclang_rt.cfi - // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-scei-ps4 -fuse-ld=ld \ // RUN: -shared \ Index: cfe/trunk/lib/Driver/SanitizerArgs.cpp === --- cfe/trunk/lib/Driver/SanitizerArgs.cpp +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp @@ -171,19 +171,23 @@ } bool SanitizerArgs::needsUbsanRt() const { - return ((Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || - CoverageFeatures) && - !Sanitizers.has(Address) && !Sanitizers.has(Memory) && - !Sanitizers.has(Thread) && !Sanitizers.has(DataFlow) && - !Sanitizers.has(Leak) && !CfiCrossDso; + // All of these include ubsan. + if (needsAsanRt() || needsMsanRt() || needsTsanRt() || needsDfsanRt() || + needsLsanRt() || needsCfiDiagRt()) +return false; + + return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || + CoverageFeatures; } bool SanitizerArgs::needsCfiRt() const { - return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso; + return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && + !ImplicitCfiRuntime; } bool SanitizerArgs::needsCfiDiagRt() const { - return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossD
r315923 - clang-refactor: Use llvm_unreachable in an unused override
Author: arphaman Date: Mon Oct 16 11:07:16 2017 New Revision: 315923 URL: http://llvm.org/viewvc/llvm-project?rev=315923&view=rev Log: clang-refactor: Use llvm_unreachable in an unused override As suggested by David Blaikie! Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Modified: cfe/trunk/tools/clang-refactor/ClangRefactor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-refactor/ClangRefactor.cpp?rev=315923&r1=315922&r2=315923&view=diff == --- cfe/trunk/tools/clang-refactor/ClangRefactor.cpp (original) +++ cfe/trunk/tools/clang-refactor/ClangRefactor.cpp Mon Oct 16 11:07:16 2017 @@ -315,7 +315,7 @@ public: } void handle(SymbolOccurrences Occurrences) override { -RefactoringResultConsumer::handle(std::move(Occurrences)); +llvm_unreachable("symbol occurrence results are not handled yet"); } const AtomicChanges &getSourceChanges() const { return SourceChanges; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38966: CodeGen: Fix invalid bitcasts for atomic builtins
yaxunl created this revision. Currently clang assumes the temporary variables emitted during codegen of atomic builtins have address space 0, which is not true for target triple amdgcn---amdgiz and causes invalid bitcasts. This patch fixes that. https://reviews.llvm.org/D38966 Files: lib/CodeGen/CGAtomic.cpp test/CodeGenOpenCL/atomic-ops.cl Index: test/CodeGenOpenCL/atomic-ops.cl === --- test/CodeGenOpenCL/atomic-ops.cl +++ test/CodeGenOpenCL/atomic-ops.cl @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O0 -o - -triple=amdgcn-amd-amdhsa-opencl | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O0 -o - -triple=amdgcn-amd-amdhsa-amdgizcl | opt -instnamer -S | FileCheck %s // Also test serialization of atomic operations here, to avoid duplicating the test. -// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa-opencl -// RUN: %clang_cc1 %s -cl-std=CL2.0 -include-pch %t -O0 -triple=amdgcn-amd-amdhsa-opencl -emit-llvm -o - | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa-amdgizcl +// RUN: %clang_cc1 %s -cl-std=CL2.0 -include-pch %t -O0 -triple=amdgcn-amd-amdhsa-amdgizcl -emit-llvm -o - | opt -instnamer -S | FileCheck %s #ifndef ALREADY_INCLUDED #define ALREADY_INCLUDED @@ -32,58 +32,58 @@ void fi1(atomic_int *i) { // CHECK-LABEL: @fi1 - // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst int x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); - // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("agent") seq_cst + // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("agent") seq_cst x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_device); - // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} seq_cst + // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} seq_cst x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_all_svm_devices); - // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("subgroup") seq_cst + // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("subgroup") seq_cst x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_sub_group); } void fi2(atomic_int *i) { // CHECK-LABEL: @fi2 - // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group); } void test_addr(global atomic_int *ig, private atomic_int *ip, local atomic_int *il) { // CHECK-LABEL: @test_addr // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(1)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst __opencl_atomic_store(ig, 1, memory_order_seq_cst, memory_scope_work_group); - // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(5)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst __opencl_atomic_store(ip, 1, memory_order_seq_cst, memory_scope_work_group); // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(3)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst __opencl_atomic_store(il, 1, memory_order_seq_cst, memory_scope_work_group); } void fi3(atomic_int *i, atomic_uint *ui) { // CHECK-LABEL: @fi3 - // CHECK: atomicrmw and i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: atomicrmw and i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst int x = __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_group); - // CHECK: atomicrmw min i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: atomicrmw min i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst x = __opencl_atomic_fetch_min(i, 1, memory_order_seq_cst, memory_scope_work_group); - // CHECK: atomicrmw max i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: atomicrmw max i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst x = __opencl_atomic_fetch_max(i, 1, memory_order_seq_cst, memory_scope_work_group); - // CHECK: atomicrmw umin i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst + // CHECK: atomicrmw umin i32* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst x = __opencl_atomic_fetch_min(ui, 1, memory_o
[PATCH] D38939: [clangd] Handle exit notification (proper shutdown)
rwols added inline comments. Comment at: test/clangd/authority-less-uri.test:33 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +Content-Length: 33 sammccall wrote: > Having the shutdown/exit boilerplate in every test seems unfortunate. > (I realize this isn't new here, but it's getting worse!) > > Does clangd exit cleanly on stdin EOF? If it could be made to do so, maybe we > could just have e.g. the initialize test do the full sequence, and the other > tests omit shutdown. Yeah, we could do that. Just send `{"jsonrpc":"2.0":"method":"exit"}` and don't care about the exit status. Everyone can then omit the `shutdown` request. I have a little more changes coming up for this diff: we should exit with exit status 0 if `shutdown` was received before `exit`, otherwise we should return 1. https://reviews.llvm.org/D38939 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315924 - [refactor] allow the use of refactoring diagnostics
Author: arphaman Date: Mon Oct 16 11:28:26 2017 New Revision: 315924 URL: http://llvm.org/viewvc/llvm-project?rev=315924&view=rev Log: [refactor] allow the use of refactoring diagnostics This commit allows the refactoring library to use its own set of refactoring-specific diagnostics to reports things like initiation errors. Differential Revision: https://reviews.llvm.org/D38772 Added: cfe/trunk/include/clang/Basic/DiagnosticRefactoringKinds.td cfe/trunk/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h cfe/trunk/test/Refactor/LocalRename/NoSymbolSelectedError.cpp cfe/trunk/tools/clang-refactor/ToolRefactoringResultConsumer.h Modified: cfe/trunk/include/clang/Basic/AllDiagnostics.h cfe/trunk/include/clang/Basic/CMakeLists.txt cfe/trunk/include/clang/Basic/Diagnostic.td cfe/trunk/include/clang/Basic/DiagnosticIDs.h cfe/trunk/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h cfe/trunk/include/clang/Tooling/Refactoring/RefactoringRuleContext.h cfe/trunk/include/clang/module.modulemap cfe/trunk/lib/Basic/DiagnosticIDs.cpp cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp cfe/trunk/tools/clang-refactor/ClangRefactor.cpp cfe/trunk/tools/clang-refactor/TestSupport.cpp cfe/trunk/tools/clang-refactor/TestSupport.h cfe/trunk/tools/diagtool/DiagnosticNames.cpp cfe/trunk/unittests/Tooling/RefactoringActionRulesTest.cpp Modified: cfe/trunk/include/clang/Basic/AllDiagnostics.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AllDiagnostics.h?rev=315924&r1=315923&r2=315924&view=diff == --- cfe/trunk/include/clang/Basic/AllDiagnostics.h (original) +++ cfe/trunk/include/clang/Basic/AllDiagnostics.h Mon Oct 16 11:28:26 2017 @@ -25,6 +25,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/SemaDiagnostic.h" #include "clang/Serialization/SerializationDiagnostic.h" +#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h" namespace clang { template Modified: cfe/trunk/include/clang/Basic/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/CMakeLists.txt?rev=315924&r1=315923&r2=315924&view=diff == --- cfe/trunk/include/clang/Basic/CMakeLists.txt (original) +++ cfe/trunk/include/clang/Basic/CMakeLists.txt Mon Oct 16 11:28:26 2017 @@ -14,6 +14,7 @@ clang_diag_gen(Driver) clang_diag_gen(Frontend) clang_diag_gen(Lex) clang_diag_gen(Parse) +clang_diag_gen(Refactoring) clang_diag_gen(Sema) clang_diag_gen(Serialization) clang_tablegen(DiagnosticGroups.inc -gen-clang-diag-groups Modified: cfe/trunk/include/clang/Basic/Diagnostic.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.td?rev=315924&r1=315923&r2=315924&view=diff == --- cfe/trunk/include/clang/Basic/Diagnostic.td (original) +++ cfe/trunk/include/clang/Basic/Diagnostic.td Mon Oct 16 11:28:26 2017 @@ -138,6 +138,7 @@ include "DiagnosticDriverKinds.td" include "DiagnosticFrontendKinds.td" include "DiagnosticLexKinds.td" include "DiagnosticParseKinds.td" +include "DiagnosticRefactoringKinds.td" include "DiagnosticSemaKinds.td" include "DiagnosticSerializationKinds.td" Modified: cfe/trunk/include/clang/Basic/DiagnosticIDs.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticIDs.h?rev=315924&r1=315923&r2=315924&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticIDs.h (original) +++ cfe/trunk/include/clang/Basic/DiagnosticIDs.h Mon Oct 16 11:28:26 2017 @@ -38,7 +38,8 @@ namespace clang { DIAG_SIZE_COMMENT = 100, DIAG_SIZE_CROSSTU = 100, DIAG_SIZE_SEMA = 3500, - DIAG_SIZE_ANALYSIS = 100 + DIAG_SIZE_ANALYSIS = 100, + DIAG_SIZE_REFACTORING = 1000, }; // Start position for diagnostics. enum { @@ -53,7 +54,8 @@ namespace clang { DIAG_START_CROSSTU = DIAG_START_COMMENT + DIAG_SIZE_CROSSTU, DIAG_START_SEMA = DIAG_START_CROSSTU + DIAG_SIZE_COMMENT, DIAG_START_ANALYSIS = DIAG_START_SEMA + DIAG_SIZE_SEMA, - DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + DIAG_SIZE_ANALYSIS + DIAG_START_REFACTORING = DIAG_START_ANALYSIS + DIAG_SIZE_ANALYSIS, + DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + DIAG_SIZE_REFACTORING }; class CustomDiagInfo; Added: cfe/trunk/include/clang/Basic/DiagnosticRefactoringKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticRefactoringKinds.td?rev=315924&view=auto == --- cfe/trunk/inclu
[PATCH] D38772: [refactor] allow the use of refactoring diagnostics
This revision was automatically updated to reflect the committed changes. Closed by commit rL315924: [refactor] allow the use of refactoring diagnostics (authored by arphaman). Changed prior to commit: https://reviews.llvm.org/D38772?vs=118701&id=119185#toc Repository: rL LLVM https://reviews.llvm.org/D38772 Files: cfe/trunk/include/clang/Basic/AllDiagnostics.h cfe/trunk/include/clang/Basic/CMakeLists.txt cfe/trunk/include/clang/Basic/Diagnostic.td cfe/trunk/include/clang/Basic/DiagnosticIDs.h cfe/trunk/include/clang/Basic/DiagnosticRefactoringKinds.td cfe/trunk/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h cfe/trunk/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h cfe/trunk/include/clang/Tooling/Refactoring/RefactoringRuleContext.h cfe/trunk/include/clang/module.modulemap cfe/trunk/lib/Basic/DiagnosticIDs.cpp cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp cfe/trunk/test/Refactor/LocalRename/NoSymbolSelectedError.cpp cfe/trunk/tools/clang-refactor/ClangRefactor.cpp cfe/trunk/tools/clang-refactor/TestSupport.cpp cfe/trunk/tools/clang-refactor/TestSupport.h cfe/trunk/tools/clang-refactor/ToolRefactoringResultConsumer.h cfe/trunk/tools/diagtool/DiagnosticNames.cpp cfe/trunk/unittests/Tooling/RefactoringActionRulesTest.cpp Index: cfe/trunk/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h === --- cfe/trunk/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h +++ cfe/trunk/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h @@ -0,0 +1,30 @@ +//===--- RefactoringDiagnostic.h - --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/PartialDiagnostic.h" + +namespace clang { +namespace diag { +enum { +#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ + SHOWINSYSHEADER, CATEGORY)\ + ENUM, +#define REFACTORINGSTART +#include "clang/Basic/DiagnosticRefactoringKinds.inc" +#undef DIAG + NUM_BUILTIN_REFACTORING_DIAGNOSTICS +}; +} // end namespace diag +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H Index: cfe/trunk/include/clang/Tooling/Refactoring/RefactoringRuleContext.h === --- cfe/trunk/include/clang/Tooling/Refactoring/RefactoringRuleContext.h +++ cfe/trunk/include/clang/Tooling/Refactoring/RefactoringRuleContext.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H #define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H +#include "clang/Basic/DiagnosticError.h" #include "clang/Basic/SourceManager.h" namespace clang { @@ -50,6 +51,17 @@ void setASTContext(ASTContext &Context) { AST = &Context; } + /// Creates an llvm::Error value that contains a diagnostic. + /// + /// The errors should not outlive the context. + llvm::Error createDiagnosticError(SourceLocation Loc, unsigned DiagID) { +return DiagnosticError::create(Loc, PartialDiagnostic(DiagID, DiagStorage)); + } + + llvm::Error createDiagnosticError(unsigned DiagID) { +return createDiagnosticError(SourceLocation(), DiagID); + } + private: /// The source manager for the translation unit / file on which a refactoring /// action might operate on. @@ -60,6 +72,8 @@ /// An optional AST for the translation unit on which a refactoring action /// might operate on. ASTContext *AST = nullptr; + /// The allocator for diagnostics. + PartialDiagnostic::StorageAllocator DiagStorage; }; } // end namespace tooling Index: cfe/trunk/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h === --- cfe/trunk/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h +++ cfe/trunk/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H #include "clang/Basic/LLVM.h" +#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h" #include "clang/Tooling/Refactoring/RefactoringOption.h" #include "clang/Tooling/Refactoring/RefactoringRuleContext.h" #include "llvm/Support/Error.h" @@ -47,10 +48,7 @@ Expected evaluate(RefactoringRuleContext &Context) const { if (Context.getSelectionRange().isValid()) return Context.getSelectionRange(); -// FIXME: Use a diagnostic. -return llvm::m
[PATCH] D38883: [CMake][OpenMP] Customize default offloading arch
gtbercea added a comment. LGTM https://reviews.llvm.org/D38883 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D37905: [libclang, bindings]: add spelling location
frutiger updated this revision to Diff 119191. frutiger added a comment. Added 'Location' to '__all__'. https://reviews.llvm.org/D37905 Files: bindings/python/clang/cindex.py bindings/python/tests/cindex/test_location.py tools/libclang/CXSourceLocation.cpp Index: tools/libclang/CXSourceLocation.cpp === --- tools/libclang/CXSourceLocation.cpp +++ tools/libclang/CXSourceLocation.cpp @@ -318,8 +318,7 @@ const SourceManager &SM = *static_cast(location.ptr_data[0]); - // FIXME: This should call SourceManager::getSpellingLoc(). - SourceLocation SpellLoc = SM.getFileLoc(Loc); + SourceLocation SpellLoc = SM.getSpellingLoc(Loc); std::pair LocInfo = SM.getDecomposedLoc(SpellLoc); FileID FID = LocInfo.first; unsigned FileOffset = LocInfo.second; Index: bindings/python/tests/cindex/test_location.py === --- bindings/python/tests/cindex/test_location.py +++ bindings/python/tests/cindex/test_location.py @@ -93,3 +93,10 @@ location3 = SourceLocation.from_position(tu, file, 1, 6) range3 = SourceRange.from_locations(location1, location3) assert range1 != range3 + +def test_spelling_location(): +tu = get_tu('''#define ONE int one +ONE;''') +one = get_cursor(tu, 'one') +assert one.location.spelling.line == 1 +assert one.location.expansion.line == 2 Index: bindings/python/clang/cindex.py === --- bindings/python/clang/cindex.py +++ bindings/python/clang/cindex.py @@ -211,25 +211,45 @@ assert isinstance(res, _CXString) return conf.lib.clang_getCString(res) +class Location(object): +"""A Location is a specific kind of source location. A SourceLocation +refers to several kinds of locations (e.g. spelling location vs. expansion +location).""" + +def __init__(self, file, line, column, offset): +self._file = File(file) if file else None +self._line = int(line.value) +self._column = int(column.value) +self._offset = int(offset.value) + + +@property +def file(self): +"""Get the file represented by this source location.""" +return self._file + +@property +def line(self): +"""Get the line represented by this source location.""" +return self._line + +@property +def column(self): +"""Get the column represented by this source location.""" +return self._column + +@property +def offset(self): +"""Get the file offset represented by this source location.""" +return self._offset class SourceLocation(Structure): """ A SourceLocation represents a particular location within a source file. """ _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)] -_data = None - -def _get_instantiation(self): -if self._data is None: -f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint() -conf.lib.clang_getInstantiationLocation(self, byref(f), byref(l), -byref(c), byref(o)) -if f: -f = File(f) -else: -f = None -self._data = (f, int(l.value), int(c.value), int(o.value)) -return self._data +_expansion = None +_spelling = None @staticmethod def from_position(tu, file, line, column): @@ -249,25 +269,73 @@ """ return conf.lib.clang_getLocationForOffset(tu, file, offset) +@property +def expansion(self): +""" +The source location where then entity this object is referring to is +expanded. +""" +if not self._expansion: +file = c_object_p() +line = c_uint() +column = c_uint() +offset = c_uint() +conf.lib.clang_getExpansionLocation(self, +byref(file), +byref(line), +byref(column), +byref(offset)) + +self._expansion = Location(file, line, column, offset) +return self._expansion + +@property +def spelling(self): +""" +The source location where then entity this object is referring to is +written. +""" +if not self._spelling: +file = c_object_p() +line = c_uint() +column = c_uint() +offset = c_uint() +conf.lib.clang_getSpellingLocation(self, + byref(file), + byref(line), + byref(column), + byref(offset)) + +self._spelling = Location(file,
[PATCH] D38968: [OpenMP] Implement omp_is_initial_device() as builtin
Hahnfeld created this revision. This allows to return the static value that we know at compile time. https://reviews.llvm.org/D38968 Files: include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h lib/AST/ExprConstant.cpp lib/Basic/Builtins.cpp test/OpenMP/is_initial_device.c Index: test/OpenMP/is_initial_device.c === --- /dev/null +++ test/OpenMP/is_initial_device.c @@ -0,0 +1,36 @@ +// REQUIRES: powerpc-registered-target + +// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-unknown-unknown \ +// RUN:-emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x ir -triple powerpc64le-unknown-unknown -emit-llvm \ +// RUN: %t-ppc-host.bc -o - | FileCheck %s -check-prefixes HOST,OUTLINED +// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -emit-llvm -fopenmp-is-device \ +// RUN: %s -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefixes DEVICE,OUTLINED + +// expected-no-diagnostics +int check() { + int host = omp_is_initial_device(); + int device; +#pragma omp target map(tofrom: device) + { +device = omp_is_initial_device(); + } + + return host + device; +} + +// The host should get a value of 1: +// HOST: define{{.*}} @check() +// HOST: [[HOST:%.*]] = alloca i32 +// HOST: store i32 1, i32* [[HOST]] + +// OUTLINED: define{{.*}} @{{.*}}omp_offloading{{.*}}(i32*{{.*}} [[DEVICE_ARGUMENT:%.*]]) +// OUTLINED: [[DEVICE_ADDR_STORAGE:%.*]] = alloca i32* +// OUTLINED: store i32* [[DEVICE_ARGUMENT]], i32** [[DEVICE_ADDR_STORAGE]] +// OUTLINED: [[DEVICE_ADDR:%.*]] = load i32*, i32** [[DEVICE_ADDR_STORAGE]] + +// The outlined function that is called as fallback also runs on the host: +// HOST: store i32 1, i32* [[DEVICE_ADDR]] + +// The device should get a value of 0: +// DEVICE: store i32 0, i32* [[DEVICE_ADDR]] Index: lib/Basic/Builtins.cpp === --- lib/Basic/Builtins.cpp +++ lib/Basic/Builtins.cpp @@ -75,8 +75,9 @@ (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES) == OCLC20_LANG; bool OclCUnsupported = !LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES); + bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG; return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported && - !OclC1Unsupported && !OclC2Unsupported && + !OclC1Unsupported && !OclC2Unsupported && !OpenMPUnsupported && !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported; } Index: lib/AST/ExprConstant.cpp === --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -7929,6 +7929,9 @@ return BuiltinOp == Builtin::BI__atomic_always_lock_free ? Success(0, E) : Error(E); } + case Builtin::BIomp_is_initial_device: +// We can decide statically which value the runtime would return if called. +return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E); } } Index: include/clang/Basic/Builtins.h === --- include/clang/Basic/Builtins.h +++ include/clang/Basic/Builtins.h @@ -38,6 +38,7 @@ MS_LANG = 0x10, // builtin requires MS mode. OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only. OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only. + OMP_LANG = 0x80,// builtin requires OpenMP. ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages. ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG,// builtin requires MS mode. Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -1434,6 +1434,9 @@ BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut") BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt") +// OpenMP 4.0 +LANGBUILTIN(omp_is_initial_device, "i", "nc", OMP_LANG) + // Builtins for XRay BUILTIN(__xray_customevent, "vcC*z", "") Index: test/OpenMP/is_initial_device.c === --- /dev/null +++ test/OpenMP/is_initial_device.c @@ -0,0 +1,36 @@ +// REQUIRES: powerpc-registered-target + +// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-unknown-unknown \ +// RUN:-emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x ir -triple powerpc64le-unknown-unknown -emit-llvm \ +// RUN: %t-ppc-host.bc -o - | FileCheck %s -check-prefixes HOST,OUTLINED +// RUN: %clang_cc1 -verify -fopenmp -x c -triple powerpc64le-unknown-unknown -emit-llvm -fopenmp-is-de
[PATCH] D38969: Sort Attributes by "HeaderName"
erichkeane created this revision. Attributes in the docs were previously sorted (apparently) by the attribute name, so AnyX86Interrupt ended up being the first one, rather than in a meaningful place. This resulted in the 4 'interrupt' titled sections being all in different places. This replaces it with a naive alphabetical sort (case sensitive, underscore and special characters first, etc). https://reviews.llvm.org/D38969 Files: utils/TableGen/ClangAttrEmitter.cpp Index: utils/TableGen/ClangAttrEmitter.cpp === --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -3663,9 +3663,14 @@ public: const Record *Documentation; const Record *Attribute; + std::string Heading; + unsigned SupportedSpellings; - DocumentationData(const Record &Documentation, const Record &Attribute) - : Documentation(&Documentation), Attribute(&Attribute) {} + DocumentationData(const Record &Documentation, const Record &Attribute, +const std::pair &&HeadingAndKinds) + : Documentation(&Documentation), Attribute(&Attribute), +Heading(HeadingAndKinds.first), +SupportedSpellings(HeadingAndKinds.second) {} }; static void WriteCategoryHeader(const Record *DocCategory, @@ -3691,16 +3696,17 @@ Pragma = 1 << 6 }; -static void WriteDocumentation(RecordKeeper &Records, - const DocumentationData &Doc, raw_ostream &OS) { +static std::pair +GetAttributeHeadingAndSpellingKinds(const Record &Documentation, +const Record &Attribute) { // FIXME: there is no way to have a per-spelling category for the attribute // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. - std::vector Spellings = GetFlattenedSpellings(*Doc.Attribute); + std::vector Spellings = GetFlattenedSpellings(Attribute); // Determine the heading to be used for this attribute. - std::string Heading = Doc.Documentation->getValueAsString("Heading"); + std::string Heading = Documentation.getValueAsString("Heading"); bool CustomHeading = !Heading.empty(); if (Heading.empty()) { // If there's only one spelling, we can simply use that. @@ -3722,7 +3728,7 @@ // If the heading is still empty, it is an error. if (Heading.empty()) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "This attribute requires a heading to be specified"); // Gather a list of unique spellings; this is not the same as the semantic @@ -3765,29 +3771,33 @@ } Heading += ")"; } - OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n"; - if (!SupportedSpellings) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "Attribute has no supported spellings; cannot be " "documented"); + return std::make_pair(std::move(Heading), SupportedSpellings); +} + +static void WriteDocumentation(RecordKeeper &Records, + const DocumentationData &Doc, raw_ostream &OS) { + OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; // List what spelling syntaxes the attribute supports. OS << ".. csv-table:: Supported Syntaxes\n"; OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\","; OS << " \"Pragma\", \"Pragma clang attribute\"\n\n"; OS << " \""; - if (SupportedSpellings & GNU) OS << "X"; + if (Doc.SupportedSpellings & GNU) OS << "X"; OS << "\",\""; - if (SupportedSpellings & CXX11) OS << "X"; + if (Doc.SupportedSpellings & CXX11) OS << "X"; OS << "\",\""; - if (SupportedSpellings & C2x) OS << "X"; + if (Doc.SupportedSpellings & C2x) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Declspec) OS << "X"; + if (Doc.SupportedSpellings & Declspec) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Keyword) OS << "X"; + if (Doc.SupportedSpellings & Keyword) OS << "X"; OS << "\", \""; - if (SupportedSpellings & Pragma) OS << "X"; + if (Doc.SupportedSpellings & Pragma) OS << "X"; OS << "\", \""; if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute)) OS << "X"; @@ -3842,18 +3852,24 @@ if (Undocumented && Docs.size() > 1) PrintFatalError(Doc.getLoc(), "Attribute is \"Undocumented\", but has multiple " -"documentation categories"); +"documentation categories"); if (!Undocumented) -SplitDocs[Category].push_back(DocumentationData(Doc, Attr)); +SplitDocs[Category].push_back(DocumentationData( +Doc, Attr, GetAttributeHeadingAndSpellingKinds(Doc, Attr))); } } // Having split the attributes out based on what documentation goes where, // we can b
[PATCH] D38969: Sort Attributes by "HeaderName"
erichkeane added a comment. Additionally, I'm going to edit the 'interrupt' docs in a separate commit to give each a separate header name based on the architecture. Currently they are all named 'interrupt', so I want to rename them all interrupt (x86), etc. Look for a future review! Comment at: utils/TableGen/ClangAttrEmitter.cpp:3666 const Record *Attribute; + std::string Heading; + unsigned SupportedSpellings; These two cannot be 'const', otherwise operator= is suppressed. Thus, std::sort won't work (Requires ValueSwappable). Comment at: utils/TableGen/ClangAttrEmitter.cpp:3865 // we can begin to generate sections of documentation. - for (const auto &I : SplitDocs) { + for (auto &I : SplitDocs) { WriteCategoryHeader(I.first, OS); Had to remove const, since the sort actually modifies the map. https://reviews.llvm.org/D38969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38970: Clarify the 'interrupt' names in Attribute Docs
erichkeane created this revision. All 4 of the 'interrupt' headers were automatically named 'interrupt'. This patch gives them unique names. https://reviews.llvm.org/D38970 Files: include/clang/Basic/AttrDocs.td Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -1290,6 +1290,7 @@ def ARMInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (ARM)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on ARM targets. This attribute may be attached to a function definition and @@ -1331,6 +1332,7 @@ def MipsInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (MIPS)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on MIPS targets. This attribute may be attached to a function definition and instructs @@ -1427,6 +1429,7 @@ def AVRInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (AVR)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt))`` attribute on AVR targets. This attribute may be attached to a function definition and instructs @@ -2789,6 +2792,7 @@ def AnyX86InterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (X86)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt))`` attribute on x86/x86-64 targets.The compiler generates function entry and exit sequences Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -1290,6 +1290,7 @@ def ARMInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (ARM)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on ARM targets. This attribute may be attached to a function definition and @@ -1331,6 +1332,7 @@ def MipsInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (MIPS)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on MIPS targets. This attribute may be attached to a function definition and instructs @@ -1427,6 +1429,7 @@ def AVRInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (AVR)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt))`` attribute on AVR targets. This attribute may be attached to a function definition and instructs @@ -2789,6 +2792,7 @@ def AnyX86InterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (X86)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt))`` attribute on x86/x86-64 targets.The compiler generates function entry and exit sequences ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38968: [OpenMP] Implement omp_is_initial_device() as builtin
ABataev accepted this revision. ABataev added a comment. This revision is now accepted and ready to land. LG https://reviews.llvm.org/D38968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38969: Sort Attributes by "HeaderName"
erichkeane added inline comments. Comment at: utils/TableGen/ClangAttrEmitter.cpp:3670 + DocumentationData(const Record &Documentation, const Record &Attribute, +const std::pair &&HeadingAndKinds) + : Documentation(&Documentation), Attribute(&Attribute), Craig brought up that I could just take by value and move out of 'first', which is more flexible for usage. New patch incoming once it passes a build. https://reviews.llvm.org/D38969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38969: Sort Attributes by "HeaderName"
erichkeane updated this revision to Diff 119195. erichkeane added a comment. Change the constructor in DocumentationData to take by value. https://reviews.llvm.org/D38969 Files: utils/TableGen/ClangAttrEmitter.cpp Index: utils/TableGen/ClangAttrEmitter.cpp === --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -3663,9 +3663,14 @@ public: const Record *Documentation; const Record *Attribute; + std::string Heading; + unsigned SupportedSpellings; - DocumentationData(const Record &Documentation, const Record &Attribute) - : Documentation(&Documentation), Attribute(&Attribute) {} + DocumentationData(const Record &Documentation, const Record &Attribute, +const std::pair HeadingAndKinds) + : Documentation(&Documentation), Attribute(&Attribute), +Heading(std::move(HeadingAndKinds.first)), +SupportedSpellings(HeadingAndKinds.second) {} }; static void WriteCategoryHeader(const Record *DocCategory, @@ -3691,16 +3696,17 @@ Pragma = 1 << 6 }; -static void WriteDocumentation(RecordKeeper &Records, - const DocumentationData &Doc, raw_ostream &OS) { +static std::pair +GetAttributeHeadingAndSpellingKinds(const Record &Documentation, +const Record &Attribute) { // FIXME: there is no way to have a per-spelling category for the attribute // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. - std::vector Spellings = GetFlattenedSpellings(*Doc.Attribute); + std::vector Spellings = GetFlattenedSpellings(Attribute); // Determine the heading to be used for this attribute. - std::string Heading = Doc.Documentation->getValueAsString("Heading"); + std::string Heading = Documentation.getValueAsString("Heading"); bool CustomHeading = !Heading.empty(); if (Heading.empty()) { // If there's only one spelling, we can simply use that. @@ -3722,7 +3728,7 @@ // If the heading is still empty, it is an error. if (Heading.empty()) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "This attribute requires a heading to be specified"); // Gather a list of unique spellings; this is not the same as the semantic @@ -3765,29 +3771,33 @@ } Heading += ")"; } - OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n"; - if (!SupportedSpellings) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "Attribute has no supported spellings; cannot be " "documented"); + return std::make_pair(std::move(Heading), SupportedSpellings); +} + +static void WriteDocumentation(RecordKeeper &Records, + const DocumentationData &Doc, raw_ostream &OS) { + OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; // List what spelling syntaxes the attribute supports. OS << ".. csv-table:: Supported Syntaxes\n"; OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\","; OS << " \"Pragma\", \"Pragma clang attribute\"\n\n"; OS << " \""; - if (SupportedSpellings & GNU) OS << "X"; + if (Doc.SupportedSpellings & GNU) OS << "X"; OS << "\",\""; - if (SupportedSpellings & CXX11) OS << "X"; + if (Doc.SupportedSpellings & CXX11) OS << "X"; OS << "\",\""; - if (SupportedSpellings & C2x) OS << "X"; + if (Doc.SupportedSpellings & C2x) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Declspec) OS << "X"; + if (Doc.SupportedSpellings & Declspec) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Keyword) OS << "X"; + if (Doc.SupportedSpellings & Keyword) OS << "X"; OS << "\", \""; - if (SupportedSpellings & Pragma) OS << "X"; + if (Doc.SupportedSpellings & Pragma) OS << "X"; OS << "\", \""; if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute)) OS << "X"; @@ -3842,18 +3852,24 @@ if (Undocumented && Docs.size() > 1) PrintFatalError(Doc.getLoc(), "Attribute is \"Undocumented\", but has multiple " -"documentation categories"); +"documentation categories"); if (!Undocumented) -SplitDocs[Category].push_back(DocumentationData(Doc, Attr)); +SplitDocs[Category].push_back(DocumentationData( +Doc, Attr, GetAttributeHeadingAndSpellingKinds(Doc, Attr))); } } // Having split the attributes out based on what documentation goes where, // we can begin to generate sections of documentation. - for (const auto &I : SplitDocs) { + for (auto &I : SplitDocs) { WriteCategoryHeader(I.first, OS); +std::sort(I.second.begin(), I.second.end(), + [](const DocumentationData &D1,
[PATCH] D38835: [refactor] selection: new CodeRangeASTSelection represents a set of selected consecutive statements
arphaman added inline comments. Comment at: include/clang/Tooling/Refactoring/ASTSelection.h:74 +/// An AST selection value that corresponds to a selection of a set of +/// statements that belong to one body of code (like one function). +/// hokein wrote: > I see all your tests are for function body, does it support other body, i.e. > "global namespace", "compound statement"? > > if yes, how about adding more test cases to cover it. > > ``` > // variable in global namespace > int a; // select int. > ``` > > ``` > void f() { >{ >int a; // select a. >} > } > ``` Yes, I added a couple that you suggested. Comment at: unittests/Tooling/ASTSelectionTest.cpp:688 + Source, {2, 2}, None, + [](SourceRange SelectionRange, Optional Node) { +EXPECT_TRUE(Node); hokein wrote: > I'm a bit confused here, if the selection range is none/empty, shouldn't > `SelectedASTNode` be empty? > > If this behavior is intended, I'd suggest documenting it in > `findSelectedASTNodesWithRange`. No, the AST selection will work even with a cursor location, hence it won't be empty. However, the CodeRangeASTSelection requires a non-empty selection range, so it won't work with just cursors. Repository: rL LLVM https://reviews.llvm.org/D38835 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38835: [refactor] selection: new CodeRangeASTSelection represents a set of selected consecutive statements
arphaman updated this revision to Diff 119197. arphaman marked 6 inline comments as done. arphaman added a comment. Address review comments Repository: rL LLVM https://reviews.llvm.org/D38835 Files: include/clang/Tooling/Refactoring/ASTSelection.h lib/Tooling/Refactoring/ASTSelection.cpp unittests/Tooling/ASTSelectionTest.cpp Index: unittests/Tooling/ASTSelectionTest.cpp === --- unittests/Tooling/ASTSelectionTest.cpp +++ unittests/Tooling/ASTSelectionTest.cpp @@ -29,12 +29,16 @@ class SelectionFinderVisitor : public TestVisitor { FileLocation Location; Optional SelectionRange; - llvm::function_ref)> Consumer; + llvm::function_ref)> + Consumer; public: - SelectionFinderVisitor( - FileLocation Location, Optional SelectionRange, - llvm::function_ref)> Consumer) + SelectionFinderVisitor(FileLocation Location, + Optional SelectionRange, + llvm::function_ref)> + Consumer) : Location(Location), SelectionRange(SelectionRange), Consumer(Consumer) { } @@ -50,20 +54,35 @@ SourceLocation Loc = Location.translate(SM); SelRange = SourceRange(Loc, Loc); } -Consumer(findSelectedASTNodes(Context, SelRange)); +Consumer(SelRange, findSelectedASTNodes(Context, SelRange)); return false; } }; -void findSelectedASTNodes( +void findSelectedASTNodesWithRange( StringRef Source, FileLocation Location, Optional SelectionRange, -llvm::function_ref)> Consumer, +llvm::function_ref)> +Consumer, SelectionFinderVisitor::Language Language = SelectionFinderVisitor::Lang_CXX11) { SelectionFinderVisitor Visitor(Location, SelectionRange, Consumer); EXPECT_TRUE(Visitor.runOver(Source, Language)); } +void findSelectedASTNodes( +StringRef Source, FileLocation Location, Optional SelectionRange, +llvm::function_ref)> Consumer, +SelectionFinderVisitor::Language Language = +SelectionFinderVisitor::Lang_CXX11) { + findSelectedASTNodesWithRange( + Source, Location, SelectionRange, + [&](SourceRange, Optional Selection) { +Consumer(std::move(Selection)); + }, + Language); +} + void checkNodeImpl(bool IsTypeMatched, const SelectedASTNode &Node, SourceSelectionKind SelectionKind, unsigned NumChildren) { ASSERT_TRUE(IsTypeMatched); @@ -649,4 +668,171 @@ SelectionFinderVisitor::Lang_OBJC); } +TEST(ASTSelectionFinder, SimpleCodeRangeASTSelection) { + StringRef Source = R"(void f(int x, int y) { + int z = x; + f(2, 3); + if (x == 0) { +return; + } + x = 1; + return; +} +void f2() { + int m = 0; +} +)"; + // No selection range. + findSelectedASTNodesWithRange( + Source, {2, 2}, None, + [](SourceRange SelectionRange, Optional Node) { +EXPECT_TRUE(Node); +Optional SelectedCode = +CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); +EXPECT_FALSE(SelectedCode); + }); + findSelectedASTNodesWithRange( + Source, {2, 2}, FileRange{{2, 2}, {2, 2}}, + [](SourceRange SelectionRange, Optional Node) { +EXPECT_TRUE(Node); +Optional SelectedCode = +CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); +EXPECT_FALSE(SelectedCode); + }); + // Range that spans multiple functions is an invalid code range. + findSelectedASTNodesWithRange( + Source, {2, 2}, FileRange{{7, 2}, {12, 1}}, + [](SourceRange SelectionRange, Optional Node) { +EXPECT_TRUE(Node); +Optional SelectedCode = +CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); +EXPECT_FALSE(SelectedCode); + }); + // Just 'z = x;': + findSelectedASTNodesWithRange( + Source, {2, 2}, FileRange{{2, 2}, {2, 13}}, + [](SourceRange SelectionRange, Optional Node) { +EXPECT_TRUE(Node); +Optional SelectedCode = +CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); +EXPECT_TRUE(SelectedCode); +EXPECT_EQ(SelectedCode->size(), 1u); +EXPECT_TRUE(isa((*SelectedCode)[0])); +ArrayRef Parents = +SelectedCode->getParents(); +EXPECT_EQ(Parents.size(), 3u); +EXPECT_TRUE( +isa(Parents[0].get().Node.get())); +// Function 'f' definition. +EXPECT_TRUE(isa(Parents[1].get().Node.get())); +// Function body of function 'F'. +EXPECT_TRUE(isa(Parents[2].get().Node.get())); + }); + // From 'f(2,3)' until just before 'x = 1;': + findSelectedASTNodesWithRange( + Source, {3, 2}, FileRange{{3, 2}, {7, 1}}, + [](SourceRange SelectionRange, Optional Node) { +EXPECT_TRUE(Node); +Optional SelectedCode = +CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); +EXPECT_TRUE(SelectedCode); +EX
[PATCH] D38939: [clangd] Handle exit notification (proper shutdown)
rwols updated this revision to Diff 119198. rwols added a comment. Return 0 if shutdown was received before exit, otherwise return 1 The protocol.test test fails now. https://reviews.llvm.org/D38939 Files: clangd/ClangdLSPServer.cpp clangd/ClangdLSPServer.h clangd/Protocol.h clangd/ProtocolHandlers.cpp clangd/ProtocolHandlers.h clangd/tool/ClangdMain.cpp test/clangd/authority-less-uri.test test/clangd/completion-priorities.test test/clangd/completion-qualifiers.test test/clangd/completion-snippet.test test/clangd/completion.test test/clangd/definitions.test test/clangd/diagnostics-preamble.test test/clangd/diagnostics.test test/clangd/did-change-watch-files.test test/clangd/extra-flags.test test/clangd/fixits.test test/clangd/formatting.test test/clangd/initialize-params-invalid.test test/clangd/initialize-params.test test/clangd/input-mirror.test test/clangd/signature-help.test test/clangd/unsupported-method.test Index: test/clangd/unsupported-method.test === --- test/clangd/unsupported-method.test +++ test/clangd/unsupported-method.test @@ -17,3 +17,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":2,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":2,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/signature-help.test === --- test/clangd/signature-help.test +++ test/clangd/signature-help.test @@ -40,3 +40,7 @@ Content-Length: 49 {"jsonrpc":"2.0","id":10,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":10,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/input-mirror.test === --- test/clangd/input-mirror.test +++ test/clangd/input-mirror.test @@ -152,3 +152,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/initialize-params.test === --- test/clangd/initialize-params.test +++ test/clangd/initialize-params.test @@ -20,3 +20,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/initialize-params-invalid.test === --- test/clangd/initialize-params-invalid.test +++ test/clangd/initialize-params-invalid.test @@ -20,3 +20,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/formatting.test === --- test/clangd/formatting.test +++ test/clangd/formatting.test @@ -65,3 +65,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":6,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":6,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/fixits.test === --- test/clangd/fixits.test +++ test/clangd/fixits.test @@ -26,3 +26,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/extra-flags.test === --- test/clangd/extra-flags.test +++ test/clangd/extra-flags.test @@ -18,5 +18,9 @@ Content-Length: 44 {"jsonrpc":"2.0","id":5,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":5,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/did-change-watch-files.test === --- test/clangd/did-change-watch-files.test +++ test/clangd/did-change-watch-files.test @@ -59,3 +59,6 @@ Content-Length: 44 {"jsonrpc":"2.0","id":3,"method":"shutdown"} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/diagnostics.test === --- test/clangd/diagnostics.test +++ test/clangd/diagnostics.test @@ -15,3 +15,7 @@ Content-Length: 44 {"jsonrpc":"2.0","id":5,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":5,"result":null} +Content-Length: 33 + +{"jsonrpc":"2.0":"method":"exit"} Index: test/clangd/diagnostics-preamble.test === --- test/clangd/diagnostics-preamble.test +++ test/clangd/diagnostics-preamble.test @@ -13,3 +13,7 @@ Content-Length: 58 {"jsonrpc":"2.0","id":2,"method":"shutdown","params":null} +# CHECK: {"jsonrpc":"2.0",
[PATCH] D38939: [clangd] Handle exit notification (proper shutdown)
rwols added a comment. I couldn't get the protocol.test to succeed; `clangd` returns 1 now and that trips up `lit`. I think I have to use `XFAIL` from `lit` somehow but didn't figure it out. https://reviews.llvm.org/D38939 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38970: Clarify the 'interrupt' names in Attribute Docs
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM, thank you! https://reviews.llvm.org/D38970 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315929 - Clarify the 'interrupt' names in Attribute Docs
Author: erichkeane Date: Mon Oct 16 13:13:36 2017 New Revision: 315929 URL: http://llvm.org/viewvc/llvm-project?rev=315929&view=rev Log: Clarify the 'interrupt' names in Attribute Docs All 4 of the 'interrupt' headers were automatically named 'interrupt'. This patch gives them unique names. Modified: cfe/trunk/include/clang/Basic/AttrDocs.td Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=315929&r1=315928&r2=315929&view=diff == --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon Oct 16 13:13:36 2017 @@ -1290,6 +1290,7 @@ Here is an example: def ARMInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (ARM)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on ARM targets. This attribute may be attached to a function definition and @@ -1331,6 +1332,7 @@ The semantics are as follows: def MipsInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (MIPS)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on MIPS targets. This attribute may be attached to a function definition and instructs @@ -1427,6 +1429,7 @@ as ``-mlong-calls`` and ``-mno-long-call def AVRInterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (AVR)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt))`` attribute on AVR targets. This attribute may be attached to a function definition and instructs @@ -2789,6 +2792,7 @@ Marking virtual functions as ``disable_t def AnyX86InterruptDocs : Documentation { let Category = DocCatFunction; + let Heading = "interrupt (X86)"; let Content = [{ Clang supports the GNU style ``__attribute__((interrupt))`` attribute on x86/x86-64 targets.The compiler generates function entry and exit sequences ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38969: Sort Attributes by "HeaderName"
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM, thank you! https://reviews.llvm.org/D38969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38969: Sort Attributes by "HeaderName"
This revision was automatically updated to reflect the committed changes. Closed by commit rL315931: Sort Attributes by "HeaderName" (authored by erichkeane). Changed prior to commit: https://reviews.llvm.org/D38969?vs=119195&id=119200#toc Repository: rL LLVM https://reviews.llvm.org/D38969 Files: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Index: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp === --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp @@ -3663,9 +3663,14 @@ public: const Record *Documentation; const Record *Attribute; + std::string Heading; + unsigned SupportedSpellings; - DocumentationData(const Record &Documentation, const Record &Attribute) - : Documentation(&Documentation), Attribute(&Attribute) {} + DocumentationData(const Record &Documentation, const Record &Attribute, +const std::pair HeadingAndKinds) + : Documentation(&Documentation), Attribute(&Attribute), +Heading(std::move(HeadingAndKinds.first)), +SupportedSpellings(HeadingAndKinds.second) {} }; static void WriteCategoryHeader(const Record *DocCategory, @@ -3691,16 +3696,17 @@ Pragma = 1 << 6 }; -static void WriteDocumentation(RecordKeeper &Records, - const DocumentationData &Doc, raw_ostream &OS) { +static std::pair +GetAttributeHeadingAndSpellingKinds(const Record &Documentation, +const Record &Attribute) { // FIXME: there is no way to have a per-spelling category for the attribute // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. - std::vector Spellings = GetFlattenedSpellings(*Doc.Attribute); + std::vector Spellings = GetFlattenedSpellings(Attribute); // Determine the heading to be used for this attribute. - std::string Heading = Doc.Documentation->getValueAsString("Heading"); + std::string Heading = Documentation.getValueAsString("Heading"); bool CustomHeading = !Heading.empty(); if (Heading.empty()) { // If there's only one spelling, we can simply use that. @@ -3722,7 +3728,7 @@ // If the heading is still empty, it is an error. if (Heading.empty()) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "This attribute requires a heading to be specified"); // Gather a list of unique spellings; this is not the same as the semantic @@ -3765,29 +3771,33 @@ } Heading += ")"; } - OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n"; - if (!SupportedSpellings) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "Attribute has no supported spellings; cannot be " "documented"); + return std::make_pair(std::move(Heading), SupportedSpellings); +} + +static void WriteDocumentation(RecordKeeper &Records, + const DocumentationData &Doc, raw_ostream &OS) { + OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; // List what spelling syntaxes the attribute supports. OS << ".. csv-table:: Supported Syntaxes\n"; OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\","; OS << " \"Pragma\", \"Pragma clang attribute\"\n\n"; OS << " \""; - if (SupportedSpellings & GNU) OS << "X"; + if (Doc.SupportedSpellings & GNU) OS << "X"; OS << "\",\""; - if (SupportedSpellings & CXX11) OS << "X"; + if (Doc.SupportedSpellings & CXX11) OS << "X"; OS << "\",\""; - if (SupportedSpellings & C2x) OS << "X"; + if (Doc.SupportedSpellings & C2x) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Declspec) OS << "X"; + if (Doc.SupportedSpellings & Declspec) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Keyword) OS << "X"; + if (Doc.SupportedSpellings & Keyword) OS << "X"; OS << "\", \""; - if (SupportedSpellings & Pragma) OS << "X"; + if (Doc.SupportedSpellings & Pragma) OS << "X"; OS << "\", \""; if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute)) OS << "X"; @@ -3842,18 +3852,24 @@ if (Undocumented && Docs.size() > 1) PrintFatalError(Doc.getLoc(), "Attribute is \"Undocumented\", but has multiple " -"documentation categories"); +"documentation categories"); if (!Undocumented) -SplitDocs[Category].push_back(DocumentationData(Doc, Attr)); +SplitDocs[Category].push_back(DocumentationData( +Doc, Attr, GetAttributeHeadingAndSpellingKinds(Doc, Attr))); } } // Having split the attributes out based on what documentation goes where, // we can begin to generate sections of documentation. - for (const auto &I : SplitDocs) {
r315931 - Sort Attributes by "HeaderName"
Author: erichkeane Date: Mon Oct 16 13:31:05 2017 New Revision: 315931 URL: http://llvm.org/viewvc/llvm-project?rev=315931&view=rev Log: Sort Attributes by "HeaderName" Attributes in the docs were previously sorted (apparently) by the attribute name, so AnyX86Interrupt ended up being the first one, rather than in a meaningful place. This resulted in the 4 'interrupt' titled sections being all in different places. This replaces it with a naive alphabetical sort (case sensitive, underscore and special characters first, etc). Differential Revision: https://reviews.llvm.org/D38969 Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=315931&r1=315930&r2=315931&view=diff == --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Oct 16 13:31:05 2017 @@ -3663,9 +3663,14 @@ class DocumentationData { public: const Record *Documentation; const Record *Attribute; + std::string Heading; + unsigned SupportedSpellings; - DocumentationData(const Record &Documentation, const Record &Attribute) - : Documentation(&Documentation), Attribute(&Attribute) {} + DocumentationData(const Record &Documentation, const Record &Attribute, +const std::pair HeadingAndKinds) + : Documentation(&Documentation), Attribute(&Attribute), +Heading(std::move(HeadingAndKinds.first)), +SupportedSpellings(HeadingAndKinds.second) {} }; static void WriteCategoryHeader(const Record *DocCategory, @@ -3691,16 +3696,17 @@ enum SpellingKind { Pragma = 1 << 6 }; -static void WriteDocumentation(RecordKeeper &Records, - const DocumentationData &Doc, raw_ostream &OS) { +static std::pair +GetAttributeHeadingAndSpellingKinds(const Record &Documentation, +const Record &Attribute) { // FIXME: there is no way to have a per-spelling category for the attribute // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. - std::vector Spellings = GetFlattenedSpellings(*Doc.Attribute); + std::vector Spellings = GetFlattenedSpellings(Attribute); // Determine the heading to be used for this attribute. - std::string Heading = Doc.Documentation->getValueAsString("Heading"); + std::string Heading = Documentation.getValueAsString("Heading"); bool CustomHeading = !Heading.empty(); if (Heading.empty()) { // If there's only one spelling, we can simply use that. @@ -3722,7 +3728,7 @@ static void WriteDocumentation(RecordKee // If the heading is still empty, it is an error. if (Heading.empty()) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "This attribute requires a heading to be specified"); // Gather a list of unique spellings; this is not the same as the semantic @@ -3765,29 +3771,33 @@ static void WriteDocumentation(RecordKee } Heading += ")"; } - OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n"; - if (!SupportedSpellings) -PrintFatalError(Doc.Attribute->getLoc(), +PrintFatalError(Attribute.getLoc(), "Attribute has no supported spellings; cannot be " "documented"); + return std::make_pair(std::move(Heading), SupportedSpellings); +} + +static void WriteDocumentation(RecordKeeper &Records, + const DocumentationData &Doc, raw_ostream &OS) { + OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; // List what spelling syntaxes the attribute supports. OS << ".. csv-table:: Supported Syntaxes\n"; OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\","; OS << " \"Pragma\", \"Pragma clang attribute\"\n\n"; OS << " \""; - if (SupportedSpellings & GNU) OS << "X"; + if (Doc.SupportedSpellings & GNU) OS << "X"; OS << "\",\""; - if (SupportedSpellings & CXX11) OS << "X"; + if (Doc.SupportedSpellings & CXX11) OS << "X"; OS << "\",\""; - if (SupportedSpellings & C2x) OS << "X"; + if (Doc.SupportedSpellings & C2x) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Declspec) OS << "X"; + if (Doc.SupportedSpellings & Declspec) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Keyword) OS << "X"; + if (Doc.SupportedSpellings & Keyword) OS << "X"; OS << "\", \""; - if (SupportedSpellings & Pragma) OS << "X"; + if (Doc.SupportedSpellings & Pragma) OS << "X"; OS << "\", \""; if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute)) OS << "X"; @@ -3842,18 +3852,24 @@ void EmitClangAttrDocs(RecordKeeper &Rec if (Undocumented && Docs.size() > 1)
[PATCH] D38968: [OpenMP] Implement omp_is_initial_device() as builtin
grokos added a comment. Now that this issue has been addressed and regressions tests pass, should we re-enable Cmake to build libomptarget by default? https://reviews.llvm.org/D38968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315934 - Remove AnyX86Interrupt documentation
Author: erichkeane Date: Mon Oct 16 13:44:14 2017 New Revision: 315934 URL: http://llvm.org/viewvc/llvm-project?rev=315934&view=rev Log: Remove AnyX86Interrupt documentation This documentation was copied directly from the GCC documentaiton in r257867. Reverting and alterting the original author so that it can be rewritten in copyright-safe language. Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=315934&r1=315933&r2=315934&view=diff == --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Mon Oct 16 13:44:14 2017 @@ -2044,7 +2044,7 @@ def AnyX86Interrupt : InheritableAttr, T let Subjects = SubjectList<[HasFunctionProto]>; let ParseKind = "Interrupt"; let HasCustomParsing = 1; - let Documentation = [AnyX86InterruptDocs]; + let Documentation = [Undocumented]; } def AnyX86NoCallerSavedRegisters : InheritableAttr, Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=315934&r1=315933&r2=315934&view=diff == --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon Oct 16 13:44:14 2017 @@ -2790,60 +2790,6 @@ Marking virtual functions as ``disable_t }]; } -def AnyX86InterruptDocs : Documentation { - let Category = DocCatFunction; - let Heading = "interrupt (X86)"; - let Content = [{ -Clang supports the GNU style ``__attribute__((interrupt))`` attribute on -x86/x86-64 targets.The compiler generates function entry and exit sequences -suitable for use in an interrupt handler when this attribute is present. -The 'IRET' instruction, instead of the 'RET' instruction, is used to return -from interrupt or exception handlers. All registers, except for the EFLAGS -register which is restored by the 'IRET' instruction, are preserved by the -compiler. - -Any interruptible-without-stack-switch code must be compiled with --mno-red-zone since interrupt handlers can and will, because of the -hardware design, touch the red zone. - -1. interrupt handler must be declared with a mandatory pointer argument: - - .. code-block:: c - -struct interrupt_frame -{ - uword_t ip; - uword_t cs; - uword_t flags; - uword_t sp; - uword_t ss; -}; - -__attribute__ ((interrupt)) -void f (struct interrupt_frame *frame) { - ... -} - -2. exception handler: - - The exception handler is very similar to the interrupt handler with - a different mandatory function signature: - - .. code-block:: c - -__attribute__ ((interrupt)) -void f (struct interrupt_frame *frame, uword_t error_code) { - ... -} - - and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction. - - The exception handler should only be used for exceptions which push an - error code and all other exceptions must use the interrupt handler. - The system will crash if the wrong handler is used. - }]; -} - def AnyX86NoCallerSavedRegistersDocs : Documentation { let Category = DocCatFunction; let Content = [{ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38968: [OpenMP] Implement omp_is_initial_device() as builtin
Hahnfeld added a comment. In https://reviews.llvm.org/D38968#898951, @grokos wrote: > Now that this issue has been addressed and regressions tests pass, should we > re-enable Cmake to build libomptarget by default? Yes, I already have a local patch which also takes care of restricting the tests to Clang versions newer than 6.0.0. I will post it for review once I've committed this revision. https://reviews.llvm.org/D38968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38639: [clangd] #include statements support for Open definition
Nebiroth marked 21 inline comments as done. Nebiroth added inline comments. Comment at: clangd/ClangdUnit.cpp:103 + void AfterExecute(CompilerInstance &CI) override { +const SourceManager &SM = CI.getSourceManager(); ilya-biryukov wrote: > There's a much better public API to get all includes that were encountered by > the `Preprocessor`: we need to override `PPCallbacks ::InclusionDirective`. > > > `PrecompiledPreamble` does not currently expose this callbacks, but could you > add to `PreambleCallbacks` in a separate commit? > If I were to use InclusionDirective , how would that callback be called automatically? As far as I know, it wouldn't be called automatically for every file that gets indexed the same way AfterExecute would be. https://reviews.llvm.org/D38639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38770: AMDGPU: Use stricter bounds for workitem builtins
arsenm updated this revision to Diff 119209. arsenm added a comment. Use 1024 for OpenCL https://reviews.llvm.org/D38770 Files: include/clang/Basic/TargetInfo.h lib/Basic/Targets/AMDGPU.cpp lib/Basic/Targets/AMDGPU.h lib/CodeGen/CGBuiltin.cpp test/CodeGenOpenCL/builtins-amdgcn.cl test/CodeGenOpenCL/builtins-r600.cl Index: test/CodeGenOpenCL/builtins-r600.cl === --- test/CodeGenOpenCL/builtins-r600.cl +++ test/CodeGenOpenCL/builtins-r600.cl @@ -52,4 +52,4 @@ } } -// CHECK-DAG: [[WI_RANGE]] = !{i32 0, i32 1024} +// CHECK-DAG: [[WI_RANGE]] = !{i32 0, i32 256} Index: test/CodeGenOpenCL/builtins-amdgcn.cl === --- test/CodeGenOpenCL/builtins-amdgcn.cl +++ test/CodeGenOpenCL/builtins-amdgcn.cl @@ -507,7 +507,7 @@ *out = __builtin_amdgcn_s_getpc(); } -// CHECK-DAG: [[WI_RANGE]] = !{i32 0, i32 1024} +// CHECK-DAG: [[WI_RANGE]] = !{i32 0, i32 256} // CHECK-DAG: attributes #[[NOUNWIND_READONLY:[0-9]+]] = { nounwind readonly } // CHECK-DAG: attributes #[[READ_EXEC_ATTRS]] = { convergent } // CHECK-DAG: ![[EXEC]] = !{!"exec"} Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -9137,22 +9137,28 @@ // amdgcn workitem case AMDGPU::BI__builtin_amdgcn_workitem_id_x: -return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024); +return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, + getContext().getTargetInfo().getOpenCLMaxWorkGroupSize(0)); case AMDGPU::BI__builtin_amdgcn_workitem_id_y: -return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024); +return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, + getContext().getTargetInfo().getOpenCLMaxWorkGroupSize(1)); case AMDGPU::BI__builtin_amdgcn_workitem_id_z: -return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024); +return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, + getContext().getTargetInfo().getOpenCLMaxWorkGroupSize(2)); // r600 intrinsics case AMDGPU::BI__builtin_r600_recipsqrt_ieee: case AMDGPU::BI__builtin_r600_recipsqrt_ieeef: return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee); case AMDGPU::BI__builtin_r600_read_tidig_x: -return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024); +return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, + getContext().getTargetInfo().getOpenCLMaxWorkGroupSize(0)); case AMDGPU::BI__builtin_r600_read_tidig_y: -return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024); +return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, + getContext().getTargetInfo().getOpenCLMaxWorkGroupSize(1)); case AMDGPU::BI__builtin_r600_read_tidig_z: -return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024); +return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, + getContext().getTargetInfo().getOpenCLMaxWorkGroupSize(2)); default: return nullptr; } Index: lib/Basic/Targets/AMDGPU.h === --- lib/Basic/Targets/AMDGPU.h +++ lib/Basic/Targets/AMDGPU.h @@ -70,6 +70,10 @@ bool hasLDEXPF : 1; const AddrSpace AS; + // The maximum supported group size is 1024, but some runtimes currently only + // support 256. + unsigned MaxWorkGroupSize = 1024; + static bool hasFullSpeedFMAF32(StringRef GPUName) { return parseAMDGCNName(GPUName) >= GK_GFX9; } @@ -283,6 +287,10 @@ return getLangASFromTargetAS(AS.Constant); } + unsigned getOpenCLMaxWorkGroupSize(unsigned Dim) const override { +return MaxWorkGroupSize; + } + /// \returns Target specific vtbl ptr address space. unsigned getVtblPtrAddressSpace() const override { return AS.Constant; } Index: lib/Basic/Targets/AMDGPU.cpp === --- lib/Basic/Targets/AMDGPU.cpp +++ lib/Basic/Targets/AMDGPU.cpp @@ -344,7 +344,7 @@ void AMDGPUTargetInfo::adjust(LangOptions &Opts) { TargetInfo::adjust(Opts); setAddressSpaceMap(Opts.OpenCL || !isAMDGCN(getTriple())); -} + ArrayRef AMDGPUTargetInfo::getTargetBuiltins() const { return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin - Index: include/clang/Basic/TargetInfo.h === --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -1056,6 +1056,11 @@ /// \brief Get address space for OpenCL type. virtual LangAS getOpenCLTypeAddrSpace(const Type *T) const; + /// \returns Maximum device supported OpenCL workgroup size. + virtual unsigned getOpenCLMaxWorkGroupSize(unsigned Dim) const { +return 0; + } + /// \returns Target specific vtbl pt
[PATCH] D38976: [OpenMP] Add implicit data sharing support when offloading to NVIDIA GPUs using OpenMP device offloading
gtbercea created this revision. Herald added a subscriber: jholewinski. This patch is part of the development effort to add support in the current OpenMP GPU offloading implementation for implicitly sharing variables between a target region executed by the team master thread and the worker threads within that team. This patch is the first of three required for successfully performing the implicit sharing of master thread variables with the worker threads within a team. The remaining two patches are: - a patch to the LLVM NVPTX backend which ensures the lowering of shared variables to an device memory which allows the sharing of references; - a runtime patch to libomptarget which ensures that a list of references to shared variables is properly maintained. A simple code snippet which illustrates an implicit data sharing situation is as follows: #pragma omp target { // master thread only int v; #pragma omp parallel { // worker threads // use v } } Variable v is implicitly shared from the team master thread which executes the code in between the target and parallel directives. The worker threads must operate on the latest version of v, including any updates performed by the master. The code generated in this patch relies on the LLVM NVPTX patch (mentioned above) which prevents v from being lowered in the thread local memory of the master thread thus making the reference to this variable un-shareable with the workers. This ensures that the code generated by this patch is correct. Since the parallel region is outlined the passing of arguments to the outlined regions must preserve the original order of arguments. The runtime therefore maintains a list of references to shared variables thus ensuring their passing in the correct order. The passing of arguments to the outlined parallel function is performed in a separate function which the data sharing infrastructure constructs in this patch. The function is inlined when optimizations are enabled. Repository: rL LLVM https://reviews.llvm.org/D38976 Files: lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp lib/CodeGen/CGOpenMPRuntimeNVPTX.h test/OpenMP/nvptx_data_sharing.cpp test/OpenMP/nvptx_parallel_codegen.cpp test/OpenMP/nvptx_target_teams_codegen.cpp Index: test/OpenMP/nvptx_target_teams_codegen.cpp === --- test/OpenMP/nvptx_target_teams_codegen.cpp +++ test/OpenMP/nvptx_target_teams_codegen.cpp @@ -60,7 +60,7 @@ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @llvm.nvvm.barrier0() - // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) + // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i8*** %shared_args) // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], @@ -146,7 +146,7 @@ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @llvm.nvvm.barrier0() - // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) + // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i8*** %shared_args) // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], Index: test/OpenMP/nvptx_parallel_codegen.cpp === --- test/OpenMP/nvptx_parallel_codegen.cpp +++ test/OpenMP/nvptx_parallel_codegen.cpp @@ -78,7 +78,7 @@ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @llvm.nvvm.barrier0() - // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) + // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], @@ -92,20 +92,20 @@ // // CHECK: [[EXEC_PARALLEL]] // CHECK: [[WF1:%.+]] = load i8*, i8** [[OMP_WORK_FN]], - // CHECK: [[WM1:%.+]] = icmp eq i8* [[WF1]], bitcast (void (i32*, i32*)* [[PARALLEL_FN1:@.+]] to i8*) + // CHECK: [[WM1:%.+]] = icmp eq i8* [[WF1]], bitcast (void (i16, i32, i8**)* [[PARALLEL_FN1:@.+]]_wrapper to i8*) // CHECK: br i1 [[WM1]], label {{%?}}[[EXEC_PFN1:.+]], label {{%?}}[[CHECK_NEXT1:.+]] // // CHECK: [[EXEC_PFN1]] - // CHECK: call void [[PARALLEL_FN1]]( + // CHECK: call void [[PARALLEL_FN1]]_wrapper( // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] // // CHECK: [[CHECK_NEXT1]] // CHECK: [[WF2:%.+]] = load i8*, i8** [[OMP_WORK_FN]], - // CHECK: [[WM2:%.+]] = icmp eq i8* [[WF2]], bitcast (void (i32*, i32*)* [[PARALLEL_FN2:@.+]] to i8*) + // CHECK: [[WM2:%.+]] = icmp eq i8* [[WF2]], bitcast (void (i16, i32, i8**)* [[PARALLEL_FN2:@.+]]_wrapper to i8*) // CHECK: br i1 [[WM2]], label {{%
[PATCH] D38978: [OpenMP] Enable the lowering of implicitly shared variables in OpenMP GPU-offloaded target regions to the GPU shared memory
gtbercea created this revision. Herald added subscribers: mgorny, jholewinski. This patch is part of the development effort to add support in the current OpenMP GPU offloading implementation for implicitly sharing variables between a target region executed by the team master thread and the worker threads within that team. This patch is the second of three required for successfully performing the implicit sharing of master thread variables with the worker threads within a team: -Patch https://reviews.llvm.org/D38976 extends the CLANG code generation with code that handles shared variables. -Patch (coming soon) extends the functionality of libomptarget to maintain a list of references to shared variables. This patch adds a shared memory stack to the prolog of the kernel function representing the device offloaded OpenMP target region. The new passes along with the changes to existing ones, ensure that any OpenMP variable which needs to be shared across several threads will be allocated in this new stack, in the shared memory of the device. This patch covers the case of sharing variables from the master thread to the worker threads: #pragma omp target { // master thread only int v; #pragma omp parallel { // worker threads // use v } } Repository: rL LLVM https://reviews.llvm.org/D38978 Files: include/llvm/CodeGen/TargetPassConfig.h lib/CodeGen/TargetPassConfig.cpp lib/Target/NVPTX/CMakeLists.txt lib/Target/NVPTX/NVPTX.h lib/Target/NVPTX/NVPTXAsmPrinter.cpp lib/Target/NVPTX/NVPTXAssignValidGlobalNames.cpp lib/Target/NVPTX/NVPTXFrameLowering.cpp lib/Target/NVPTX/NVPTXFunctionDataSharing.cpp lib/Target/NVPTX/NVPTXFunctionDataSharing.h lib/Target/NVPTX/NVPTXInstrInfo.td lib/Target/NVPTX/NVPTXLowerAlloca.cpp lib/Target/NVPTX/NVPTXLowerSharedFrameIndicesPass.cpp lib/Target/NVPTX/NVPTXRegisterInfo.cpp lib/Target/NVPTX/NVPTXRegisterInfo.h lib/Target/NVPTX/NVPTXRegisterInfo.td lib/Target/NVPTX/NVPTXTargetMachine.cpp lib/Target/NVPTX/NVPTXUtilities.cpp lib/Target/NVPTX/NVPTXUtilities.h Index: lib/Target/NVPTX/NVPTXUtilities.h === --- lib/Target/NVPTX/NVPTXUtilities.h +++ lib/Target/NVPTX/NVPTXUtilities.h @@ -14,6 +14,8 @@ #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H #define LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H +#include "NVPTXTargetMachine.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IntrinsicInst.h" @@ -60,6 +62,8 @@ bool getAlign(const Function &, unsigned index, unsigned &); bool getAlign(const CallInst &, unsigned index, unsigned &); +bool ptrIsStored(Value *Ptr); + } #endif Index: lib/Target/NVPTX/NVPTXUtilities.cpp === --- lib/Target/NVPTX/NVPTXUtilities.cpp +++ lib/Target/NVPTX/NVPTXUtilities.cpp @@ -28,6 +28,8 @@ namespace llvm { +#define DEBUG_TYPE "nvptx-utilities" + namespace { typedef std::map > key_val_pair_t; typedef std::map global_val_annot_t; @@ -314,4 +316,50 @@ return false; } +/// Returns true if there are any instructions storing +/// the address of this pointer. +bool ptrIsStored(Value *Ptr) { + SmallVector PointerAliases; + PointerAliases.push_back(Ptr); + + SmallVector Users; + for (const Use &U : Ptr->uses()) +Users.push_back(U.getUser()); + + for (unsigned I = 0; I < Users.size(); ++I) { +// Get pointer usage +const User *FU = Users[I]; + +// Check if Ptr or an alias to it is the destination of the store +auto SI = dyn_cast(FU); +if (SI) { + for (auto Alias: PointerAliases) +if (SI->getValueOperand() == Alias) + return true; + continue; +} + +// TODO: Can loads lead to address being taken? +// TODO: Can GEPs lead to address being taken? + +// Bitcasts increase aliases of the pointer +auto BI = dyn_cast(FU); +if (BI) { + for (const Use &U : BI->uses()) +Users.push_back(U.getUser()); + PointerAliases.push_back(BI); + continue; +} + +// TODO: +// There may be other instructions which increase the number +// of alias values ex. operations on the address of the alloca. +// The whole alloca'ed memory region needs to be shared if at +// least one of the values needs to be shared. + } + + // Address of the pointer has been stored + return false; +} + } // namespace llvm Index: lib/Target/NVPTX/NVPTXTargetMachine.cpp === --- lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -54,6 +54,7 @@ void initializeNVPTXLowerAggrCopiesPass(PassRegistry &); void initializeNVPTXLowerArgsPass(PassRegistry &); void initializeNVPTXLowerAllocaPass(PassRegistry &); +void initializeNVPTXFunctionDataSharingPass(PassRegistry &); } // end namespac
[PATCH] D38979: Fix usage in TableGen of getValueAsString
erichkeane created this revision. Record::getValueAsString returns a stringref to an interned string (apparently had been changed since most of tablegen was written). In this patch, I audited the usage of getValueAsString to find places where we can trivially stop storing 'std::string' and instead keep the stringref. There was one instance where an unnecessary 'stringstream' was being used, so that has been removed as well to unblock the stringref replacing string fix. https://reviews.llvm.org/D38979 Files: utils/TableGen/ClangAttrEmitter.cpp Index: utils/TableGen/ClangAttrEmitter.cpp === --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -1440,7 +1440,7 @@ assert(!SpellingList.empty() && "Attribute with empty spelling list can't have accessors!"); for (const auto *Accessor : Accessors) { -std::string Name = Accessor->getValueAsString("Name"); +const StringRef Name = Accessor->getValueAsString("Name"); std::vector Spellings = GetFlattenedSpellings(*Accessor); OS << " bool " << Name << "() const { return SpellingListIndex == "; @@ -1589,7 +1589,7 @@ // Abstract rules are used only for sub-rules bool isAbstractRule() const { return getSubjects().empty(); } - std::string getName() const { + StringRef getName() const { return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name"); } @@ -1821,13 +1821,11 @@ // Generate a function that constructs a set of matching rules that describe // to which declarations the attribute should apply to. std::string FnName = "matchRulesFor" + Attr.getName().str(); - std::stringstream SS; - SS << "static void " << FnName << "(llvm::SmallVectorImpl> &MatchRules, const LangOptions &LangOpts) {\n"; if (Attr.isValueUnset("Subjects")) { -SS << "}\n\n"; -OS << SS.str(); +OS << "}\n\n"; return FnName; } const Record *SubjectObj = Attr.getValueAsDef("Subjects"); @@ -1840,24 +1838,23 @@ // The rule might be language specific, so only subtract it from the given // rules if the specific language options are specified. std::vector LangOpts = Rule.getLangOpts(); - SS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() + OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() << ", /*IsSupported=*/"; if (!LangOpts.empty()) { for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { - std::string Part = (*I)->getValueAsString("Name"); + const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) -SS << "!"; - SS << "LangOpts." + Part; +OS << "!"; + OS << "LangOpts." << Part; if (I + 1 != E) -SS << " || "; +OS << " || "; } } else -SS << "true"; - SS << "));\n"; +OS << "true"; + OS << "));\n"; } } - SS << "}\n\n"; - OS << SS.str(); + OS << "}\n\n"; return FnName; } @@ -1913,7 +1910,8 @@ continue; std::string SubRuleFunction; if (SubMatchRules.count(Rule.MetaSubject)) - SubRuleFunction = "isAttributeSubjectMatchSubRuleFor_" + Rule.getName(); + SubRuleFunction = + ("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str(); else SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor"; OS << " Case(\"" << Rule.getName() << "\", std::make_pair(" @@ -3030,7 +3028,7 @@ static std::string CalculateDiagnostic(const Record &S) { // If the SubjectList object has a custom diagnostic associated with it, // return that directly. - std::string CustomDiag = S.getValueAsString("CustomDiag"); + const StringRef CustomDiag = S.getValueAsString("CustomDiag"); if (!CustomDiag.empty()) return CustomDiag; @@ -3314,12 +3312,13 @@ // codegen efficiency). std::string FnName = "check", Test; for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { -std::string Part = (*I)->getValueAsString("Name"); +const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) { FnName += "Not"; Test += "!"; } -Test += "S.LangOpts." + Part; +Test += "S.LangOpts."; +Test += Part; if (I + 1 != E) Test += " || "; FnName += Part; @@ -3375,7 +3374,7 @@ // applies to multiple target architectures. In order for the attribute to be // considered valid, all of its architectures need to be included. if (!Attr.isValueUnset("ParseKind")) { -std::string APK = Attr.getValueAsString("ParseKind"); +const StringRef APK = Attr.getValueAsString("ParseKind"); for (const auto &I : Dupes) { if (I.first == APK) { std::vector DA = @@ -3675,13 +3674,13 @@ static void WriteCategoryHeader(const Record *DocCategory,
[PATCH] D38979: Fix usage in TableGen of getValueAsString
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM, thank you for the cleanup! https://reviews.llvm.org/D38979 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315950 - Replace usage of std::stringstream with raw_string_ostream
Author: erichkeane Date: Mon Oct 16 15:47:26 2017 New Revision: 315950 URL: http://llvm.org/viewvc/llvm-project?rev=315950&view=rev Log: Replace usage of std::stringstream with raw_string_ostream Typically we don't use the stringstream, so instead use raw_string_stream. Additionally, the dependent function changed to use raw_ostream. Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=315950&r1=315949&r2=315950&view=diff == --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Oct 16 15:47:26 2017 @@ -2998,7 +2998,7 @@ static bool isArgVariadic(const Record & return createArgument(R, AttrName)->isVariadic(); } -static void emitArgInfo(const Record &R, std::stringstream &OS) { +static void emitArgInfo(const Record &R, raw_ostream &OS) { // This function will count the number of arguments specified for the // attribute and emit the number of required arguments followed by the // number of optional arguments. @@ -3471,7 +3471,8 @@ void EmitClangAttrParsedAttrImpl(RecordK // another mapping. At the same time, generate the AttrInfoMap object // contents. Due to the reliance on generated code, use separate streams so // that code will not be interleaved. - std::stringstream SS; + std::string Buffer; + raw_string_ostream SS {Buffer}; for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { // TODO: If the attribute's kind appears in the list of duplicates, that is // because it is a target-specific attribute that appears multiple times. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315951 - Make __builtin_types_compatible_p more like GCC's
Author: gbiv Date: Mon Oct 16 15:58:37 2017 New Revision: 315951 URL: http://llvm.org/viewvc/llvm-project?rev=315951&view=rev Log: Make __builtin_types_compatible_p more like GCC's GCC ignore qualifiers on array types. Since we seem to have this function primarily for GCC compatibility, we should try to match that behavior. This also adds a few more test-cases __builtin_types_compatible_p, which were inspired by GCC's documentation on the builtin. Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/Parser/builtin_types_compatible.c Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=315951&r1=315950&r2=315951&view=diff == --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Oct 16 15:58:37 2017 @@ -4824,9 +4824,13 @@ static bool EvaluateBinaryTypeTrait(Sema } case BTT_IsSame: return Self.Context.hasSameType(LhsT, RhsT); - case BTT_TypeCompatible: -return Self.Context.typesAreCompatible(LhsT.getUnqualifiedType(), - RhsT.getUnqualifiedType()); + case BTT_TypeCompatible: { +// GCC ignores cv-qualifiers on arrays for this builtin. +Qualifiers LhsQuals, RhsQuals; +QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals); +QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals); +return Self.Context.typesAreCompatible(Lhs, Rhs); + } case BTT_IsConvertible: case BTT_IsConvertibleTo: { // C++0x [meta.rel]p4: Modified: cfe/trunk/test/Parser/builtin_types_compatible.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/builtin_types_compatible.c?rev=315951&r1=315950&r2=315951&view=diff == --- cfe/trunk/test/Parser/builtin_types_compatible.c (original) +++ cfe/trunk/test/Parser/builtin_types_compatible.c Mon Oct 16 15:58:37 2017 @@ -41,3 +41,20 @@ static void test() } +enum E1 { E1Foo }; +enum E2 { E2Foo }; + +static void testGccCompatibility() { + _Static_assert(__builtin_types_compatible_p(const volatile int, int), ""); + _Static_assert(__builtin_types_compatible_p(int[5], int[]), ""); + _Static_assert(!__builtin_types_compatible_p(int[5], int[4]), ""); + _Static_assert(!__builtin_types_compatible_p(int *, int **), ""); + _Static_assert(!__builtin_types_compatible_p(const int *, int *), ""); + _Static_assert(!__builtin_types_compatible_p(enum E1, enum E2), ""); + + // GCC's __builtin_types_compatible_p ignores qualifiers on arrays. + _Static_assert(__builtin_types_compatible_p(const int[4], int[4]), ""); + _Static_assert(__builtin_types_compatible_p(int[4], const int[4]), ""); + _Static_assert(__builtin_types_compatible_p(const int[5][4], int[][4]), ""); + _Static_assert(!__builtin_types_compatible_p(const int(*)[], int(*)[]), ""); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r315951 - Make __builtin_types_compatible_p more like GCC's
Yuck, sorry for the typos in the commit message. It should read: GCC ignores qualifiers on array types. Since we seem to have this function primarily for GCC compatibility, we should try to match that behavior. This also adds a few more test-cases for __builtin_types_compatible_p, which were inspired by GCC's documentation on the builtin. On Mon, Oct 16, 2017 at 3:58 PM, George Burgess IV via cfe-commits wrote: > Author: gbiv > Date: Mon Oct 16 15:58:37 2017 > New Revision: 315951 > > URL: http://llvm.org/viewvc/llvm-project?rev=315951&view=rev > Log: > Make __builtin_types_compatible_p more like GCC's > > GCC ignore qualifiers on array types. Since we seem to have this > function primarily for GCC compatibility, we should try to match that > behavior. > > This also adds a few more test-cases __builtin_types_compatible_p, > which were inspired by GCC's documentation on the builtin. > > Modified: > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/test/Parser/builtin_types_compatible.c > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=315951&r1=315950&r2=315951&view=diff > == > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Oct 16 15:58:37 2017 > @@ -4824,9 +4824,13 @@ static bool EvaluateBinaryTypeTrait(Sema >} >case BTT_IsSame: > return Self.Context.hasSameType(LhsT, RhsT); > - case BTT_TypeCompatible: > -return Self.Context.typesAreCompatible(LhsT.getUnqualifiedType(), > - RhsT.getUnqualifiedType()); > + case BTT_TypeCompatible: { > +// GCC ignores cv-qualifiers on arrays for this builtin. > +Qualifiers LhsQuals, RhsQuals; > +QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, > LhsQuals); > +QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, > RhsQuals); > +return Self.Context.typesAreCompatible(Lhs, Rhs); > + } >case BTT_IsConvertible: >case BTT_IsConvertibleTo: { > // C++0x [meta.rel]p4: > > Modified: cfe/trunk/test/Parser/builtin_types_compatible.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/builtin_types_compatible.c?rev=315951&r1=315950&r2=315951&view=diff > == > --- cfe/trunk/test/Parser/builtin_types_compatible.c (original) > +++ cfe/trunk/test/Parser/builtin_types_compatible.c Mon Oct 16 15:58:37 2017 > @@ -41,3 +41,20 @@ static void test() > > } > > +enum E1 { E1Foo }; > +enum E2 { E2Foo }; > + > +static void testGccCompatibility() { > + _Static_assert(__builtin_types_compatible_p(const volatile int, int), ""); > + _Static_assert(__builtin_types_compatible_p(int[5], int[]), ""); > + _Static_assert(!__builtin_types_compatible_p(int[5], int[4]), ""); > + _Static_assert(!__builtin_types_compatible_p(int *, int **), ""); > + _Static_assert(!__builtin_types_compatible_p(const int *, int *), ""); > + _Static_assert(!__builtin_types_compatible_p(enum E1, enum E2), ""); > + > + // GCC's __builtin_types_compatible_p ignores qualifiers on arrays. > + _Static_assert(__builtin_types_compatible_p(const int[4], int[4]), ""); > + _Static_assert(__builtin_types_compatible_p(int[4], const int[4]), ""); > + _Static_assert(__builtin_types_compatible_p(const int[5][4], int[][4]), > ""); > + _Static_assert(!__builtin_types_compatible_p(const int(*)[], int(*)[]), > ""); > +} > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r315953 - Don't print end-of-directive tokens in -E output
Author: rnk Date: Mon Oct 16 16:07:15 2017 New Revision: 315953 URL: http://llvm.org/viewvc/llvm-project?rev=315953&view=rev Log: Don't print end-of-directive tokens in -E output This comes up when pre-processing standalone .s files containing hash-prefixed comments. The pre-processor should skip the unknown directive and not emit an extra newline as we were doing. Fixes PR34950 Added: cfe/trunk/test/Preprocessor/print-assembler.s Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=315953&r1=315952&r2=315953&view=diff == --- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original) +++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Mon Oct 16 16:07:15 2017 @@ -720,6 +720,12 @@ static void PrintPreprocessedTokens(Prep // -traditional-cpp the lexer keeps /all/ whitespace, including comments. SourceLocation StartLoc = Tok.getLocation(); Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength())); +} else if (Tok.is(tok::eod)) { + // Don't print end of directive tokens, since they are typically newlines + // that mess up our line tracking. These come from unknown pre-processor + // directives or hash-prefixed comments in standalone assembly files. + PP.Lex(Tok); + continue; } else if (Tok.is(tok::annot_module_include)) { // PrintPPOutputPPCallbacks::InclusionDirective handles producing // appropriate output here. Ignore this token entirely. Added: cfe/trunk/test/Preprocessor/print-assembler.s URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/print-assembler.s?rev=315953&view=auto == --- cfe/trunk/test/Preprocessor/print-assembler.s (added) +++ cfe/trunk/test/Preprocessor/print-assembler.s Mon Oct 16 16:07:15 2017 @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -E -x assembler-with-cpp %s -o - | FileCheck %s --strict-whitespace + +.intel_syntax noprefix +.text + .global _main +_main: +# asdf +# asdf + mov bogus_name, 20 + mov rax, 5 + ret + +// CHECK-LABEL: _main: +// CHECK-NEXT: {{^}} # asdf +// CHECK-NEXT: {{^}} # asdf +// CHECK-NEXT: mov bogus_name, 20 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38979: Fix usage in TableGen of getValueAsString
This revision was automatically updated to reflect the committed changes. Closed by commit rL315956: Fix usage in TableGen of getValueAsString (authored by erichkeane). Changed prior to commit: https://reviews.llvm.org/D38979?vs=119218&id=119227#toc Repository: rL LLVM https://reviews.llvm.org/D38979 Files: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Index: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp === --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp @@ -1440,7 +1440,7 @@ assert(!SpellingList.empty() && "Attribute with empty spelling list can't have accessors!"); for (const auto *Accessor : Accessors) { -std::string Name = Accessor->getValueAsString("Name"); +const StringRef Name = Accessor->getValueAsString("Name"); std::vector Spellings = GetFlattenedSpellings(*Accessor); OS << " bool " << Name << "() const { return SpellingListIndex == "; @@ -1589,7 +1589,7 @@ // Abstract rules are used only for sub-rules bool isAbstractRule() const { return getSubjects().empty(); } - std::string getName() const { + StringRef getName() const { return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name"); } @@ -1821,13 +1821,11 @@ // Generate a function that constructs a set of matching rules that describe // to which declarations the attribute should apply to. std::string FnName = "matchRulesFor" + Attr.getName().str(); - std::stringstream SS; - SS << "static void " << FnName << "(llvm::SmallVectorImpl> &MatchRules, const LangOptions &LangOpts) {\n"; if (Attr.isValueUnset("Subjects")) { -SS << "}\n\n"; -OS << SS.str(); +OS << "}\n\n"; return FnName; } const Record *SubjectObj = Attr.getValueAsDef("Subjects"); @@ -1840,24 +1838,23 @@ // The rule might be language specific, so only subtract it from the given // rules if the specific language options are specified. std::vector LangOpts = Rule.getLangOpts(); - SS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() + OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() << ", /*IsSupported=*/"; if (!LangOpts.empty()) { for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { - std::string Part = (*I)->getValueAsString("Name"); + const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) -SS << "!"; - SS << "LangOpts." + Part; +OS << "!"; + OS << "LangOpts." << Part; if (I + 1 != E) -SS << " || "; +OS << " || "; } } else -SS << "true"; - SS << "));\n"; +OS << "true"; + OS << "));\n"; } } - SS << "}\n\n"; - OS << SS.str(); + OS << "}\n\n"; return FnName; } @@ -1913,7 +1910,8 @@ continue; std::string SubRuleFunction; if (SubMatchRules.count(Rule.MetaSubject)) - SubRuleFunction = "isAttributeSubjectMatchSubRuleFor_" + Rule.getName(); + SubRuleFunction = + ("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str(); else SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor"; OS << " Case(\"" << Rule.getName() << "\", std::make_pair(" @@ -3030,7 +3028,7 @@ static std::string CalculateDiagnostic(const Record &S) { // If the SubjectList object has a custom diagnostic associated with it, // return that directly. - std::string CustomDiag = S.getValueAsString("CustomDiag"); + const StringRef CustomDiag = S.getValueAsString("CustomDiag"); if (!CustomDiag.empty()) return CustomDiag; @@ -3314,12 +3312,13 @@ // codegen efficiency). std::string FnName = "check", Test; for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { -std::string Part = (*I)->getValueAsString("Name"); +const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) { FnName += "Not"; Test += "!"; } -Test += "S.LangOpts." + Part; +Test += "S.LangOpts."; +Test += Part; if (I + 1 != E) Test += " || "; FnName += Part; @@ -3375,7 +3374,7 @@ // applies to multiple target architectures. In order for the attribute to be // considered valid, all of its architectures need to be included. if (!Attr.isValueUnset("ParseKind")) { -std::string APK = Attr.getValueAsString("ParseKind"); +const StringRef APK = Attr.getValueAsString("ParseKind"); for (const auto &I : Dupes) { if (I.first == APK) { std::vector DA = @@ -3676,13 +3675,13 @@ static void WriteCategoryHeader(const Record *DocCategory, raw_ostream &OS) { - const std::string &Name = DocCategory->getValueAsString("Name"); - OS << Name << "\n" << std::string(Name.length(), '=') << "\n"; + cons
r315956 - Fix usage in TableGen of getValueAsString
Author: erichkeane Date: Mon Oct 16 16:25:24 2017 New Revision: 315956 URL: http://llvm.org/viewvc/llvm-project?rev=315956&view=rev Log: Fix usage in TableGen of getValueAsString Record::getValueAsString returns a stringref to an interned string (apparently had been changed since most of tablegen was written). In this patch, I audited the usage of getValueAsString to find places where we can trivially stop storing 'std::string' and instead keep the stringref. There was one instance where an unnecessary 'stringstream' was being used, so that has been removed as well to unblock the stringref replacing string fix. Differential Revision: https://reviews.llvm.org/D38979 Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=315956&r1=315955&r2=315956&view=diff == --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Oct 16 16:25:24 2017 @@ -1440,7 +1440,7 @@ static void writeAttrAccessorDefinition( assert(!SpellingList.empty() && "Attribute with empty spelling list can't have accessors!"); for (const auto *Accessor : Accessors) { -std::string Name = Accessor->getValueAsString("Name"); +const StringRef Name = Accessor->getValueAsString("Name"); std::vector Spellings = GetFlattenedSpellings(*Accessor); OS << " bool " << Name << "() const { return SpellingListIndex == "; @@ -1589,7 +1589,7 @@ struct AttributeSubjectMatchRule { // Abstract rules are used only for sub-rules bool isAbstractRule() const { return getSubjects().empty(); } - std::string getName() const { + StringRef getName() const { return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name"); } @@ -1821,13 +1821,11 @@ PragmaClangAttributeSupport::generateStr // Generate a function that constructs a set of matching rules that describe // to which declarations the attribute should apply to. std::string FnName = "matchRulesFor" + Attr.getName().str(); - std::stringstream SS; - SS << "static void " << FnName << "(llvm::SmallVectorImpl> &MatchRules, const LangOptions &LangOpts) {\n"; if (Attr.isValueUnset("Subjects")) { -SS << "}\n\n"; -OS << SS.str(); +OS << "}\n\n"; return FnName; } const Record *SubjectObj = Attr.getValueAsDef("Subjects"); @@ -1840,24 +1838,23 @@ PragmaClangAttributeSupport::generateStr // The rule might be language specific, so only subtract it from the given // rules if the specific language options are specified. std::vector LangOpts = Rule.getLangOpts(); - SS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() + OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() << ", /*IsSupported=*/"; if (!LangOpts.empty()) { for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { - std::string Part = (*I)->getValueAsString("Name"); + const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) -SS << "!"; - SS << "LangOpts." + Part; +OS << "!"; + OS << "LangOpts." << Part; if (I + 1 != E) -SS << " || "; +OS << " || "; } } else -SS << "true"; - SS << "));\n"; +OS << "true"; + OS << "));\n"; } } - SS << "}\n\n"; - OS << SS.str(); + OS << "}\n\n"; return FnName; } @@ -1913,7 +1910,8 @@ void PragmaClangAttributeSupport::genera continue; std::string SubRuleFunction; if (SubMatchRules.count(Rule.MetaSubject)) - SubRuleFunction = "isAttributeSubjectMatchSubRuleFor_" + Rule.getName(); + SubRuleFunction = + ("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str(); else SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor"; OS << " Case(\"" << Rule.getName() << "\", std::make_pair(" @@ -3030,7 +3028,7 @@ static void GenerateDefaultAppertainsTo( static std::string CalculateDiagnostic(const Record &S) { // If the SubjectList object has a custom diagnostic associated with it, // return that directly. - std::string CustomDiag = S.getValueAsString("CustomDiag"); + const StringRef CustomDiag = S.getValueAsString("CustomDiag"); if (!CustomDiag.empty()) return CustomDiag; @@ -3314,12 +3312,13 @@ static std::string GenerateLangOptRequir // codegen efficiency). std::string FnName = "check", Test; for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { -std::string Part = (*I)->getValueAsString("Name"); +const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) { FnName += "Not"; Test += "!"; } -Test += "S.Lan
[PATCH] D38737: [X86] test/testn intrinsics lowering to IR. clang side
craig.topper added inline comments. Comment at: lib/Headers/avx512bwintrin.h:2109 + return _mm512_cmp_epi8_mask(_mm512_and_epi32(__A, __B), +_mm512_setzero_qi(), 4); } Can you align this with the opening paren on the line above? Same with all the other functions below. https://reviews.llvm.org/D38737 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38982: [refactor] Initial outline of implementation of "extract function" refactoring
arphaman created this revision. Herald added a subscriber: mgorny. This patch adds an initial, skeleton outline of the "extract function" refactoring. The extracted function doesn't capture variables / rewrite code yet, it just basically does a simple copy-paste. The following initiation rules are specified: - extraction can only be done for executable code in a function/method/block. This means that you can't extract a global variable initialize into a function right now (should this be allowed though?). - simple literals and references are not extractable. This patch also adds support for full source ranges to clang-refactor's test mode. Repository: rL LLVM https://reviews.llvm.org/D38982 Files: include/clang/Basic/DiagnosticRefactoringKinds.td include/clang/Tooling/Refactoring/ASTSelection.h include/clang/Tooling/Refactoring/RefactoringActionRegistry.def include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h include/clang/Tooling/Refactoring/RefactoringRuleContext.h lib/Tooling/Refactoring/ASTSelection.cpp lib/Tooling/Refactoring/ASTSelectionRequirements.cpp lib/Tooling/Refactoring/CMakeLists.txt lib/Tooling/Refactoring/Extract.cpp test/Refactor/Extract/ExtractExprIntoFunction.cpp test/Refactor/LocalRename/Field.cpp test/Refactor/tool-test-support.c tools/clang-refactor/TestSupport.cpp Index: tools/clang-refactor/TestSupport.cpp === --- tools/clang-refactor/TestSupport.cpp +++ tools/clang-refactor/TestSupport.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" @@ -101,7 +102,14 @@ llvm::errs() << toString(Result.takeError()); return true; } -OS << *Result; +auto Buf = llvm::MemoryBuffer::getMemBuffer(Result->c_str()); +for (llvm::line_iterator It(*Buf, /*SkipBlanks=*/false); !It.is_at_end(); + ++It) { + // Drop the 'CHECK' lines alltogether to avoid erroneous matches. + if (It->contains("CHECK")) +continue; + OS << *It << "\n"; +} } return false; } @@ -241,9 +249,9 @@ // Dump the results: const auto &TestGroup = TestRanges.GroupedRanges[Group.index()]; if (!CanonicalResult) { - llvm::errs() << TestGroup.Ranges.size() << " '" << TestGroup.Name + llvm::outs() << TestGroup.Ranges.size() << " '" << TestGroup.Name << "' results:\n"; - llvm::errs() << *CanonicalErrorMessage << "\n"; + llvm::outs() << *CanonicalErrorMessage << "\n"; } else { llvm::outs() << TestGroup.Ranges.size() << " '" << TestGroup.Name << "' results:\n"; @@ -271,6 +279,25 @@ (NewlinePos == StringRef::npos ? ColumnOffset : (unsigned)NewlinePos); } +static unsigned addEndLineOffsetAndEndColumn(StringRef Source, unsigned Offset, + unsigned LineNumberOffset, + unsigned Column) { + StringRef Line = Source.drop_front(Offset); + unsigned LineOffset = 0; + for (; LineNumberOffset != 0; --LineNumberOffset) { +size_t NewlinePos = Line.find_first_of("\r\n"); +// Line offset goes out of bounds. +if (NewlinePos == StringRef::npos) + break; +LineOffset += NewlinePos + 1; +Line = Line.drop_front(NewlinePos + 1); + } + // Source now points to the line at +lineOffset; + size_t LineStart = Source.find_last_of("\r\n", /*From=*/Offset + LineOffset); + return addColumnOffset( + Source, LineStart == StringRef::npos ? 0 : LineStart + 1, Column - 1); +} + Optional findTestSelectionRanges(StringRef Filename) { ErrorOr> ErrOrFile = @@ -282,11 +309,11 @@ } StringRef Source = ErrOrFile.get()->getBuffer(); - // FIXME (Alex L): 3rd capture groups for +line:column. // See the doc comment for this function for the explanation of this // syntax. static Regex RangeRegex("range[[:blank:]]*([[:alpha:]_]*)?[[:blank:]]*=[[:" - "blank:]]*(\\+[[:digit:]]+)?"); + "blank:]]*(\\+[[:digit:]]+)?[[:blank:]]*(->[[:blank:]" + "]*[\\+\\:[:digit:]]+)?"); std::map> GroupedRanges; @@ -304,18 +331,22 @@ StringRef Comment = Source.substr(Tok.getLocation().getRawEncoding(), Tok.getLength()); SmallVector Matches; -// Allow CHECK: comments to contain range= commands. -if (!RangeRegex.match(Comment, &Matches) || Comment.contains("CHECK")) { - // Try to detect mistyped 'range:' comments to ensure tests don't miss - // anything. +// Try to detect mistyped 'range:' comments to ensure tests don't miss +// anything. +auto DetectMistypedCommand = [&]() ->
r315958 - [libclang] Visit attributes for function and class templates
Author: jbcoe Date: Mon Oct 16 16:43:02 2017 New Revision: 315958 URL: http://llvm.org/viewvc/llvm-project?rev=315958&view=rev Log: [libclang] Visit attributes for function and class templates Summary: Previously, `VisitAttributes` was not called for function and class templates and thus their attributes were not accessible using libclang. Reviewers: bkramer, arphaman, rsmith, jbcoe Reviewed By: jbcoe Subscribers: cfe-commits Tags: #clang Patch by jklaehn (Johann Klähn) Differential Revision: https://reviews.llvm.org/D36955 Modified: cfe/trunk/bindings/python/tests/cindex/test_cursor.py cfe/trunk/test/Index/annotate-attribute.cpp cfe/trunk/tools/libclang/CIndex.cpp Modified: cfe/trunk/bindings/python/tests/cindex/test_cursor.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/tests/cindex/test_cursor.py?rev=315958&r1=315957&r2=315958&view=diff == --- cfe/trunk/bindings/python/tests/cindex/test_cursor.py (original) +++ cfe/trunk/bindings/python/tests/cindex/test_cursor.py Mon Oct 16 16:43:02 2017 @@ -377,6 +377,26 @@ def test_annotation_attribute(): else: assert False, "Couldn't find annotation" +def test_annotation_template(): +annotation = '__attribute__ ((annotate("annotation")))' +for source, kind in [ +('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), +('class %s foo {};', CursorKind.CLASS_TEMPLATE), +]: +source = 'template ' + (source % annotation) +tu = get_tu(source, lang="cpp") + +foo = get_cursor(tu, 'foo') +assert foo is not None +assert foo.kind == kind + +for c in foo.get_children(): +if c.kind == CursorKind.ANNOTATE_ATTR: +assert c.displayname == "annotation" +break +else: +assert False, "Couldn't find annotation for {}".format(kind) + def test_result_type(): tu = get_tu('int foo();') foo = get_cursor(tu, 'foo') Modified: cfe/trunk/test/Index/annotate-attribute.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-attribute.cpp?rev=315958&r1=315957&r2=315958&view=diff == --- cfe/trunk/test/Index/annotate-attribute.cpp (original) +++ cfe/trunk/test/Index/annotate-attribute.cpp Mon Oct 16 16:43:02 2017 @@ -16,6 +16,12 @@ protected: void methodWithoutAttribute(); }; +template +class __attribute__((annotate("works"))) TemplateTest {}; + +template +int templateFunction(T value) __attribute__((annotate("works"))); + // CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2] // CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8] // CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60] @@ -31,3 +37,9 @@ protected: // CHECK-NEXT: CompoundStmt= Extent=[12:23 - 12:25] // CHECK-NEXT: CXXAccessSpecifier=:14:1 (Definition) Extent=[14:1 - 14:11] // CHECK-NEXT: CXXMethod=methodWithoutAttribute:16:8 Extent=[16:3 - 16:32] +// CHECK: ClassTemplate=TemplateTest:20:42 (Definition) Extent=[19:1 - 20:57] +// CHECK-NEXT: TemplateTypeParameter=T:19:20 (Definition) Extent=[19:11 - 19:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[20:22 - 20:39] +// CHECK: FunctionTemplate=templateFunction:23:5 Extent=[22:1 - 23:65] +// CHECK-NEXT: TemplateTypeParameter=T:22:20 (Definition) Extent=[22:11 - 22:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[23:46 - 23:63] Modified: cfe/trunk/tools/libclang/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=315958&r1=315957&r2=315958&view=diff == --- cfe/trunk/tools/libclang/CIndex.cpp (original) +++ cfe/trunk/tools/libclang/CIndex.cpp Mon Oct 16 16:43:02 2017 @@ -907,7 +907,8 @@ bool CursorVisitor::VisitFunctionTemplat if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitFunctionDecl(D->getTemplatedDecl()); + auto* FD = D->getTemplatedDecl(); + return VisitAttributes(FD) || VisitFunctionDecl(FD); } bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { @@ -916,7 +917,8 @@ bool CursorVisitor::VisitClassTemplateDe if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitCXXRecordDecl(D->getTemplatedDecl()); + auto* CD = D->getTemplatedDecl(); + return VisitAttributes(CD) || VisitCXXRecordDecl(CD); } bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36955: [libclang] Visit attributes for function and class templates
This revision was automatically updated to reflect the committed changes. Closed by commit rL315958: [libclang] Visit attributes for function and class templates (authored by jbcoe). Changed prior to commit: https://reviews.llvm.org/D36955?vs=118330&id=119233#toc Repository: rL LLVM https://reviews.llvm.org/D36955 Files: cfe/trunk/bindings/python/tests/cindex/test_cursor.py cfe/trunk/test/Index/annotate-attribute.cpp cfe/trunk/tools/libclang/CIndex.cpp Index: cfe/trunk/tools/libclang/CIndex.cpp === --- cfe/trunk/tools/libclang/CIndex.cpp +++ cfe/trunk/tools/libclang/CIndex.cpp @@ -907,16 +907,18 @@ if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitFunctionDecl(D->getTemplatedDecl()); + auto* FD = D->getTemplatedDecl(); + return VisitAttributes(FD) || VisitFunctionDecl(FD); } bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { // FIXME: Visit the "outer" template parameter lists on the TagDecl // before visiting these template parameters. if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitCXXRecordDecl(D->getTemplatedDecl()); + auto* CD = D->getTemplatedDecl(); + return VisitAttributes(CD) || VisitCXXRecordDecl(CD); } bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { Index: cfe/trunk/bindings/python/tests/cindex/test_cursor.py === --- cfe/trunk/bindings/python/tests/cindex/test_cursor.py +++ cfe/trunk/bindings/python/tests/cindex/test_cursor.py @@ -377,6 +377,26 @@ else: assert False, "Couldn't find annotation" +def test_annotation_template(): +annotation = '__attribute__ ((annotate("annotation")))' +for source, kind in [ +('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), +('class %s foo {};', CursorKind.CLASS_TEMPLATE), +]: +source = 'template ' + (source % annotation) +tu = get_tu(source, lang="cpp") + +foo = get_cursor(tu, 'foo') +assert foo is not None +assert foo.kind == kind + +for c in foo.get_children(): +if c.kind == CursorKind.ANNOTATE_ATTR: +assert c.displayname == "annotation" +break +else: +assert False, "Couldn't find annotation for {}".format(kind) + def test_result_type(): tu = get_tu('int foo();') foo = get_cursor(tu, 'foo') Index: cfe/trunk/test/Index/annotate-attribute.cpp === --- cfe/trunk/test/Index/annotate-attribute.cpp +++ cfe/trunk/test/Index/annotate-attribute.cpp @@ -16,6 +16,12 @@ void methodWithoutAttribute(); }; +template +class __attribute__((annotate("works"))) TemplateTest {}; + +template +int templateFunction(T value) __attribute__((annotate("works"))); + // CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2] // CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8] // CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60] @@ -31,3 +37,9 @@ // CHECK-NEXT: CompoundStmt= Extent=[12:23 - 12:25] // CHECK-NEXT: CXXAccessSpecifier=:14:1 (Definition) Extent=[14:1 - 14:11] // CHECK-NEXT: CXXMethod=methodWithoutAttribute:16:8 Extent=[16:3 - 16:32] +// CHECK: ClassTemplate=TemplateTest:20:42 (Definition) Extent=[19:1 - 20:57] +// CHECK-NEXT: TemplateTypeParameter=T:19:20 (Definition) Extent=[19:11 - 19:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[20:22 - 20:39] +// CHECK: FunctionTemplate=templateFunction:23:5 Extent=[22:1 - 23:65] +// CHECK-NEXT: TemplateTypeParameter=T:22:20 (Definition) Extent=[22:11 - 22:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[23:46 - 23:63] Index: cfe/trunk/tools/libclang/CIndex.cpp === --- cfe/trunk/tools/libclang/CIndex.cpp +++ cfe/trunk/tools/libclang/CIndex.cpp @@ -907,16 +907,18 @@ if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitFunctionDecl(D->getTemplatedDecl()); + auto* FD = D->getTemplatedDecl(); + return VisitAttributes(FD) || VisitFunctionDecl(FD); } bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { // FIXME: Visit the "outer" template parameter lists on the TagDecl // before visiting these template parameters. if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitCXXRecordDecl(D->getTemplatedDecl()); + auto* CD = D->getTemplatedDecl(); + return VisitAttributes(CD) || VisitCXXRecordDecl(CD); } bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { Index: cfe/trunk/bindings/python/tests/cindex/test_cursor.py === --- cfe/trunk/bindings/python/tests
[PATCH] D36973: [libclang] Add support for querying cursor availability
This revision was automatically updated to reflect the committed changes. Closed by commit rL315959: [libclang] Add support for querying cursor availability (authored by jbcoe). Changed prior to commit: https://reviews.llvm.org/D36973?vs=118333&id=119234#toc Repository: rL LLVM https://reviews.llvm.org/D36973 Files: cfe/trunk/bindings/python/clang/cindex.py cfe/trunk/bindings/python/tests/cindex/test_cursor.py Index: cfe/trunk/bindings/python/clang/cindex.py === --- cfe/trunk/bindings/python/clang/cindex.py +++ cfe/trunk/bindings/python/clang/cindex.py @@ -1587,6 +1587,16 @@ return StorageClass.from_id(self._storage_class) @property +def availability(self): +""" +Retrieves the availability of the entity pointed at by the cursor. +""" +if not hasattr(self, '_availability'): +self._availability = conf.lib.clang_getCursorAvailability(self) + +return AvailabilityKind.from_id(self._availability) + +@property def access_specifier(self): """ Retrieves the access specifier (if any) of the entity pointed at by the @@ -1923,6 +1933,24 @@ StorageClass.AUTO = StorageClass(6) StorageClass.REGISTER = StorageClass(7) +### Availability Kinds ### + +class AvailabilityKind(BaseEnumeration): +""" +Describes the availability of an entity. +""" + +# The unique kind objects, indexed by id. +_kinds = [] +_name_map = None + +def __repr__(self): +return 'AvailabilityKind.%s' % (self.name,) + +AvailabilityKind.AVAILABLE = AvailabilityKind(0) +AvailabilityKind.DEPRECATED = AvailabilityKind(1) +AvailabilityKind.NOT_AVAILABLE = AvailabilityKind(2) +AvailabilityKind.NOT_ACCESSIBLE = AvailabilityKind(3) ### C++ access specifiers ### @@ -3491,6 +3519,10 @@ [TranslationUnit, SourceLocation], Cursor), + ("clang_getCursorAvailability", + [Cursor], + c_int), + ("clang_getCursorDefinition", [Cursor], Cursor, @@ -4106,6 +4138,7 @@ register_enumerations() __all__ = [ +'AvailabilityKind', 'Config', 'CodeCompletionResults', 'CompilationDatabase', Index: cfe/trunk/bindings/python/tests/cindex/test_cursor.py === --- cfe/trunk/bindings/python/tests/cindex/test_cursor.py +++ cfe/trunk/bindings/python/tests/cindex/test_cursor.py @@ -1,6 +1,7 @@ import ctypes import gc +from clang.cindex import AvailabilityKind from clang.cindex import CursorKind from clang.cindex import TemplateArgumentKind from clang.cindex import TranslationUnit @@ -405,6 +406,30 @@ t = foo.result_type assert t.kind == TypeKind.INT +def test_availability(): +tu = get_tu('class A { A(A const&) = delete; };', lang='cpp') + +# AvailabilityKind.AVAILABLE +cursor = get_cursor(tu, 'A') +assert cursor.kind == CursorKind.CLASS_DECL +assert cursor.availability == AvailabilityKind.AVAILABLE + +# AvailabilityKind.NOT_AVAILABLE +cursors = get_cursors(tu, 'A') +for c in cursors: +if c.kind == CursorKind.CONSTRUCTOR: +assert c.availability == AvailabilityKind.NOT_AVAILABLE +break +else: +assert False, "Could not find cursor for deleted constructor" + +# AvailabilityKind.DEPRECATED +tu = get_tu('void test() __attribute__((deprecated));', lang='cpp') +cursor = get_cursor(tu, 'test') +assert cursor.availability == AvailabilityKind.DEPRECATED + +# AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results + def test_get_tokens(): """Ensure we can map cursors back to tokens.""" tu = get_tu('int foo(int i);') ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits