[clang-tools-extra] r280456 - Add clang-reorder-fields to clang-tools-extra
Alexander Shaposhnikov via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 1 19:56:08 PDT 2016
Author: alexshap
Date: Thu Sep 1 21:56:07 2016
New Revision: 280456
URL: http://llvm.org/viewvc/llvm-project?rev=280456&view=rev
Log:
Add clang-reorder-fields to clang-tools-extra
This diff adds v0 of clang-reorder-fields tool to clang/tools/extra.
The main idea behind this tool is to simplify and make less error-prone refactoring of large codebases when
someone needs to change the order fields of a struct/class (for example to remove excessive padding).
Differential revision: https://reviews.llvm.org/D23279
Added:
clang-tools-extra/trunk/clang-reorder-fields/
clang-tools-extra/trunk/clang-reorder-fields/CMakeLists.txt
clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.cpp
clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.h
clang-tools-extra/trunk/clang-reorder-fields/tool/
clang-tools-extra/trunk/clang-reorder-fields/tool/CMakeLists.txt
clang-tools-extra/trunk/clang-reorder-fields/tool/ClangReorderFields.cpp
clang-tools-extra/trunk/test/clang-reorder-fields/
clang-tools-extra/trunk/test/clang-reorder-fields/AggregatePartialInitialization.cpp
clang-tools-extra/trunk/test/clang-reorder-fields/CStructAmbiguousName.cpp
clang-tools-extra/trunk/test/clang-reorder-fields/CStructFieldsOrder.cpp
clang-tools-extra/trunk/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp
clang-tools-extra/trunk/test/clang-reorder-fields/ClassMixedInitialization.cpp
clang-tools-extra/trunk/test/clang-reorder-fields/ClassSimpleCtor.cpp
Modified:
clang-tools-extra/trunk/CMakeLists.txt
clang-tools-extra/trunk/test/CMakeLists.txt
Modified: clang-tools-extra/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/CMakeLists.txt?rev=280456&r1=280455&r2=280456&view=diff
==============================================================================
--- clang-tools-extra/trunk/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/CMakeLists.txt Thu Sep 1 21:56:07 2016
@@ -1,5 +1,6 @@
add_subdirectory(clang-apply-replacements)
add_subdirectory(clang-rename)
+add_subdirectory(clang-reorder-fields)
add_subdirectory(modularize)
if(CLANG_ENABLE_STATIC_ANALYZER)
add_subdirectory(clang-tidy)
Added: clang-tools-extra/trunk/clang-reorder-fields/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-reorder-fields/CMakeLists.txt?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-reorder-fields/CMakeLists.txt (added)
+++ clang-tools-extra/trunk/clang-reorder-fields/CMakeLists.txt Thu Sep 1 21:56:07 2016
@@ -0,0 +1,15 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangReorderFields
+ ReorderFieldsAction.cpp
+
+ LINK_LIBS
+ clangAST
+ clangASTMatchers
+ clangBasic
+ clangIndex
+ clangLex
+ clangToolingCore
+ )
+
+add_subdirectory(tool)
Added: clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.cpp (added)
+++ clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,264 @@
+//===-- tools/extra/clang-reorder-fields/ReorderFieldsAction.cpp -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the definition of the
+/// ReorderFieldsAction::newASTConsumer method
+///
+//===----------------------------------------------------------------------===//
+
+#include "ReorderFieldsAction.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Refactoring.h"
+#include <algorithm>
+#include <string>
+
+namespace clang {
+namespace reorder_fields {
+using namespace clang::ast_matchers;
+
+/// \brief Finds the definition of a record by name.
+///
+/// \returns nullptr if the name is ambiguous or not found.
+static const CXXRecordDecl *findDefinition(StringRef RecordName,
+ ASTContext &Context) {
+ auto Results = match(
+ recordDecl(hasName(RecordName), isDefinition()).bind("cxxRecordDecl"),
+ Context);
+ if (Results.empty()) {
+ llvm::errs() << "Definition of " << RecordName << " not found\n";
+ return nullptr;
+ }
+ if (Results.size() > 1) {
+ llvm::errs() << "The name " << RecordName
+ << " is ambiguous, several definitions found\n";
+ return nullptr;
+ }
+ return selectFirst<CXXRecordDecl>("cxxRecordDecl", Results);
+}
+
+/// \brief Calculates the new order of fields.
+///
+/// \returns empty vector if the list of fields doesn't match the definition.
+static SmallVector<unsigned, 4>
+getNewFieldsOrder(const CXXRecordDecl *Definition,
+ ArrayRef<std::string> DesiredFieldsOrder) {
+ assert(Definition && "Definition is null");
+
+ llvm::StringMap<unsigned> NameToIndex;
+ for (const auto *Field : Definition->fields())
+ NameToIndex[Field->getName()] = Field->getFieldIndex();
+
+ if (DesiredFieldsOrder.size() != NameToIndex.size()) {
+ llvm::errs() << "Number of provided fields doesn't match definition.\n";
+ return {};
+ }
+ SmallVector<unsigned, 4> NewFieldsOrder;
+ for (const auto &Name : DesiredFieldsOrder) {
+ if (!NameToIndex.count(Name)) {
+ llvm::errs() << "Field " << Name << " not found in definition.\n";
+ return {};
+ }
+ NewFieldsOrder.push_back(NameToIndex[Name]);
+ }
+ assert(NewFieldsOrder.size() == NameToIndex.size());
+ return NewFieldsOrder;
+}
+
+// FIXME: error-handling
+/// \brief Replaces one range of source code by another.
+static void
+addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context,
+ std::map<std::string, tooling::Replacements> &Replacements) {
+ StringRef NewText =
+ Lexer::getSourceText(CharSourceRange::getTokenRange(New),
+ Context.getSourceManager(), Context.getLangOpts());
+ tooling::Replacement R(Context.getSourceManager(),
+ CharSourceRange::getTokenRange(Old), NewText,
+ Context.getLangOpts());
+ consumeError(Replacements[R.getFilePath()].add(R));
+}
+
+/// \brief Reorders fields in the definition of a struct/class.
+///
+/// At the moment reodering of fields with
+/// different accesses (public/protected/private) is not supported.
+/// \returns true on success.
+static bool reorderFieldsInDefinition(
+ const CXXRecordDecl *Definition, ArrayRef<unsigned> NewFieldsOrder,
+ const ASTContext &Context,
+ std::map<std::string, tooling::Replacements> &Replacements) {
+ assert(Definition && "Definition is null");
+
+ SmallVector<const FieldDecl *, 10> Fields;
+ for (const auto *Field : Definition->fields())
+ Fields.push_back(Field);
+
+ // Check that the permutation of the fields doesn't change the accesses
+ for (const auto *Field : Definition->fields()) {
+ const auto FieldIndex = Field->getFieldIndex();
+ if (Field->getAccess() != Fields[NewFieldsOrder[FieldIndex]]->getAccess()) {
+ llvm::errs() << "Currently reodering of fields with different accesses "
+ "is not supported\n";
+ return false;
+ }
+ }
+
+ for (const auto *Field : Definition->fields()) {
+ const auto FieldIndex = Field->getFieldIndex();
+ if (FieldIndex == NewFieldsOrder[FieldIndex])
+ continue;
+ addReplacement(Field->getSourceRange(),
+ Fields[NewFieldsOrder[FieldIndex]]->getSourceRange(),
+ Context, Replacements);
+ }
+ return true;
+}
+
+/// \brief Reorders initializers in a C++ struct/class constructor.
+///
+/// A constructor can have initializers for an arbitrary subset of the class's fields.
+/// Thus, we need to ensure that we reorder just the initializers that are present.
+static void reorderFieldsInConstructor(
+ const CXXConstructorDecl *CtorDecl, ArrayRef<unsigned> NewFieldsOrder,
+ const ASTContext &Context,
+ std::map<std::string, tooling::Replacements> &Replacements) {
+ assert(CtorDecl && "Constructor declaration is null");
+ if (CtorDecl->isImplicit() || CtorDecl->getNumCtorInitializers() <= 1)
+ return;
+
+ // The method FunctionDecl::isThisDeclarationADefinition returns false
+ // for a defaulted function unless that function has been implicitly defined.
+ // Thus this assert needs to be after the previous checks.
+ assert(CtorDecl->isThisDeclarationADefinition() && "Not a definition");
+
+ SmallVector<unsigned, 10> NewFieldsPositions(NewFieldsOrder.size());
+ for (unsigned i = 0, e = NewFieldsOrder.size(); i < e; ++i)
+ NewFieldsPositions[NewFieldsOrder[i]] = i;
+
+ SmallVector<const CXXCtorInitializer *, 10> OldWrittenInitializersOrder;
+ SmallVector<const CXXCtorInitializer *, 10> NewWrittenInitializersOrder;
+ for (const auto *Initializer : CtorDecl->inits()) {
+ if (!Initializer->isWritten())
+ continue;
+ OldWrittenInitializersOrder.push_back(Initializer);
+ NewWrittenInitializersOrder.push_back(Initializer);
+ }
+ auto ByFieldNewPosition = [&](const CXXCtorInitializer *LHS,
+ const CXXCtorInitializer *RHS) {
+ assert(LHS && RHS);
+ return NewFieldsPositions[LHS->getMember()->getFieldIndex()] <
+ NewFieldsPositions[RHS->getMember()->getFieldIndex()];
+ };
+ std::sort(std::begin(NewWrittenInitializersOrder),
+ std::end(NewWrittenInitializersOrder), ByFieldNewPosition);
+ assert(OldWrittenInitializersOrder.size() ==
+ NewWrittenInitializersOrder.size());
+ for (unsigned i = 0, e = NewWrittenInitializersOrder.size(); i < e; ++i)
+ if (OldWrittenInitializersOrder[i] != NewWrittenInitializersOrder[i])
+ addReplacement(OldWrittenInitializersOrder[i]->getSourceRange(),
+ NewWrittenInitializersOrder[i]->getSourceRange(), Context,
+ Replacements);
+}
+
+/// \brief Reorders initializers in the brace initialization of an aggregate.
+///
+/// At the moment partial initialization is not supported.
+/// \returns true on success
+static bool reorderFieldsInInitListExpr(
+ const InitListExpr *InitListEx, ArrayRef<unsigned> NewFieldsOrder,
+ const ASTContext &Context,
+ std::map<std::string, tooling::Replacements> &Replacements) {
+ assert(InitListEx && "Init list expression is null");
+ // We care only about InitListExprs which originate from source code.
+ // Implicit InitListExprs are created by the semantic analyzer.
+ if (!InitListEx->isExplicit())
+ return true;
+ // The method InitListExpr::getSyntacticForm may return nullptr indicating that
+ // the current initializer list also serves as its syntactic form.
+ if (const auto *SyntacticForm = InitListEx->getSyntacticForm())
+ InitListEx = SyntacticForm;
+ // If there are no initializers we do not need to change anything.
+ if (!InitListEx->getNumInits())
+ return true;
+ if (InitListEx->getNumInits() != NewFieldsOrder.size()) {
+ llvm::errs() << "Currently only full initialization is supported\n";
+ return false;
+ }
+ for (unsigned i = 0, e = InitListEx->getNumInits(); i < e; ++i)
+ if (i != NewFieldsOrder[i])
+ addReplacement(
+ InitListEx->getInit(i)->getSourceRange(),
+ InitListEx->getInit(NewFieldsOrder[i])->getSourceRange(), Context,
+ Replacements);
+ return true;
+}
+
+namespace {
+class ReorderingConsumer : public ASTConsumer {
+ StringRef RecordName;
+ ArrayRef<std::string> DesiredFieldsOrder;
+ std::map<std::string, tooling::Replacements> &Replacements;
+
+public:
+ ReorderingConsumer(StringRef RecordName,
+ ArrayRef<std::string> DesiredFieldsOrder,
+ std::map<std::string, tooling::Replacements> &Replacements)
+ : RecordName(RecordName), DesiredFieldsOrder(DesiredFieldsOrder),
+ Replacements(Replacements) {}
+
+ ReorderingConsumer(const ReorderingConsumer &) = delete;
+ ReorderingConsumer &operator=(const ReorderingConsumer &) = delete;
+
+ void HandleTranslationUnit(ASTContext &Context) override {
+ const CXXRecordDecl *RD = findDefinition(RecordName, Context);
+ if (!RD)
+ return;
+ SmallVector<unsigned, 4> NewFieldsOrder =
+ getNewFieldsOrder(RD, DesiredFieldsOrder);
+ if (NewFieldsOrder.empty())
+ return;
+ if (!reorderFieldsInDefinition(RD, NewFieldsOrder, Context, Replacements))
+ return;
+ for (const auto *C : RD->ctors())
+ if (const auto *D = dyn_cast<CXXConstructorDecl>(C->getDefinition()))
+ reorderFieldsInConstructor(cast<const CXXConstructorDecl>(D),
+ NewFieldsOrder, Context, Replacements);
+
+ // We only need to reorder init list expressions for aggregate types.
+ // For other types the order of constructor parameters is used,
+ // which we don't change at the moment.
+ // Now (v0) partial initialization is not supported.
+ if (RD->isAggregate())
+ for (auto Result :
+ match(initListExpr(hasType(equalsNode(RD))).bind("initListExpr"),
+ Context))
+ if (!reorderFieldsInInitListExpr(
+ Result.getNodeAs<InitListExpr>("initListExpr"), NewFieldsOrder,
+ Context, Replacements)) {
+ Replacements.clear();
+ return;
+ }
+ }
+};
+} // end anonymous namespace
+
+std::unique_ptr<ASTConsumer> ReorderFieldsAction::newASTConsumer() {
+ return llvm::make_unique<ReorderingConsumer>(RecordName, DesiredFieldsOrder,
+ Replacements);
+}
+
+} // namespace reorder_fields
+} // namespace clang
Added: clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.h?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.h (added)
+++ clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.h Thu Sep 1 21:56:07 2016
@@ -0,0 +1,47 @@
+//===-- tools/extra/clang-reorder-fields/ReorderFieldsAction.h -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declarations of the ReorderFieldsAction class and
+/// the FieldPosition struct.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_ACTION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_ACTION_H
+
+#include "clang/Tooling/Refactoring.h"
+
+namespace clang {
+class ASTConsumer;
+
+namespace reorder_fields {
+
+class ReorderFieldsAction {
+ llvm::StringRef RecordName;
+ llvm::ArrayRef<std::string> DesiredFieldsOrder;
+ std::map<std::string, tooling::Replacements> &Replacements;
+
+public:
+ ReorderFieldsAction(
+ llvm::StringRef RecordName,
+ llvm::ArrayRef<std::string> DesiredFieldsOrder,
+ std::map<std::string, tooling::Replacements> &Replacements)
+ : RecordName(RecordName), DesiredFieldsOrder(DesiredFieldsOrder),
+ Replacements(Replacements) {}
+
+ ReorderFieldsAction(const ReorderFieldsAction &) = delete;
+ ReorderFieldsAction &operator=(const ReorderFieldsAction &) = delete;
+
+ std::unique_ptr<ASTConsumer> newASTConsumer();
+};
+} // namespace reorder_fields
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_ACTION_H
Added: clang-tools-extra/trunk/clang-reorder-fields/tool/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-reorder-fields/tool/CMakeLists.txt?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-reorder-fields/tool/CMakeLists.txt (added)
+++ clang-tools-extra/trunk/clang-reorder-fields/tool/CMakeLists.txt Thu Sep 1 21:56:07 2016
@@ -0,0 +1,12 @@
+add_clang_executable(clang-reorder-fields ClangReorderFields.cpp)
+
+target_link_libraries(clang-reorder-fields
+ clangBasic
+ clangFrontend
+ clangReorderFields
+ clangRewrite
+ clangTooling
+ clangToolingCore
+ )
+
+install(TARGETS clang-reorder-fields RUNTIME DESTINATION bin)
Added: clang-tools-extra/trunk/clang-reorder-fields/tool/ClangReorderFields.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-reorder-fields/tool/ClangReorderFields.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-reorder-fields/tool/ClangReorderFields.cpp (added)
+++ clang-tools-extra/trunk/clang-reorder-fields/tool/ClangReorderFields.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,93 @@
+//===-- tools/extra/clang-reorder-fields/tool/ClangReorderFields.cpp -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the implementation of clang-reorder-fields tool
+///
+//===----------------------------------------------------------------------===//
+
+#include "../ReorderFieldsAction.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include <cstdlib>
+#include <string>
+#include <system_error>
+
+using namespace llvm;
+using namespace clang;
+
+cl::OptionCategory ClangReorderFieldsCategory("clang-reorder-fields options");
+
+static cl::opt<std::string>
+ RecordName("record-name", cl::Required,
+ cl::desc("The name of the struct/class."),
+ cl::cat(ClangReorderFieldsCategory));
+
+static cl::list<std::string> FieldsOrder("fields-order", cl::CommaSeparated,
+ cl::OneOrMore,
+ cl::desc("The desired fields order."),
+ cl::cat(ClangReorderFieldsCategory));
+
+static cl::opt<bool> Inplace("i", cl::desc("Overwrite edited files."),
+ cl::cat(ClangReorderFieldsCategory));
+
+const char Usage[] = "A tool to reorder fields in C/C++ structs/classes.\n";
+
+int main(int argc, const char **argv) {
+ tooling::CommonOptionsParser OP(argc, argv, ClangReorderFieldsCategory,
+ Usage);
+
+ auto Files = OP.getSourcePathList();
+ tooling::RefactoringTool Tool(OP.getCompilations(), Files);
+
+ reorder_fields::ReorderFieldsAction Action(RecordName, FieldsOrder,
+ Tool.getReplacements());
+
+ auto Factory = tooling::newFrontendActionFactory(&Action);
+
+ if (Inplace)
+ return Tool.runAndSave(Factory.get());
+
+ int ExitCode = Tool.run(Factory.get());
+ LangOptions DefaultLangOptions;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
+ TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
+ DiagnosticsEngine Diagnostics(
+ IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
+ &DiagnosticPrinter, false);
+
+ auto &FileMgr = Tool.getFiles();
+ SourceManager Sources(Diagnostics, FileMgr);
+ Rewriter Rewrite(Sources, DefaultLangOptions);
+ Tool.applyAllReplacements(Rewrite);
+
+ for (const auto &File : Files) {
+ const auto *Entry = FileMgr.getFile(File);
+ const auto ID = Sources.translateFile(Entry);
+ // The method Rewriter::getRewriteBufferFor returns nullptr if
+ // the file has not been changed.
+ if (const auto *RB = Rewrite.getRewriteBufferFor(ID))
+ RB->write(outs());
+ else
+ outs() << Sources.getMemoryBufferForFile(Entry)->getBuffer();
+ }
+
+ return ExitCode;
+}
Modified: clang-tools-extra/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/CMakeLists.txt?rev=280456&r1=280455&r2=280456&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/test/CMakeLists.txt Thu Sep 1 21:56:07 2016
@@ -45,6 +45,7 @@ set(CLANG_TOOLS_TEST_DEPS
clang-include-fixer
clang-query
clang-rename
+ clang-reorder-fields
clang-tidy
find-all-symbols
modularize
Added: clang-tools-extra/trunk/test/clang-reorder-fields/AggregatePartialInitialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-reorder-fields/AggregatePartialInitialization.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-reorder-fields/AggregatePartialInitialization.cpp (added)
+++ clang-tools-extra/trunk/test/clang-reorder-fields/AggregatePartialInitialization.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,14 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order z,y,x %s -- | FileCheck %s
+
+// The order of fields should not change.
+class Foo {
+public:
+ int x; // CHECK: {{^ int x;}}
+ int y; // CHECK-NEXT: {{^ int y;}}
+ int z; // CHECK-NEXT: {{^ int z;}}
+};
+
+int main() {
+ Foo foo = { 0, 1 }; // CHECK: {{^ Foo foo = { 0, 1 };}}
+ return 0;
+}
Added: clang-tools-extra/trunk/test/clang-reorder-fields/CStructAmbiguousName.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-reorder-fields/CStructAmbiguousName.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-reorder-fields/CStructAmbiguousName.cpp (added)
+++ clang-tools-extra/trunk/test/clang-reorder-fields/CStructAmbiguousName.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,18 @@
+// RUN: clang-reorder-fields -record-name ::Foo -fields-order y,x %s -- | FileCheck %s
+
+struct Foo {
+ int x; // CHECK: {{^ double y;}}
+ double y; // CHECK-NEXT: {{^ int x;}}
+};
+
+namespace bar {
+struct Foo {
+ int x; // CHECK: {{^ int x;}}
+ double y; // CHECK-NEXT: {{^ double y;}}
+};
+} // end namespace bar
+
+int main() {
+ bar::Foo foo = { 1, 1.7 }; // CHECK: {{^ bar::Foo foo = { 1, 1.7 };}}
+ return 0;
+}
Added: clang-tools-extra/trunk/test/clang-reorder-fields/CStructFieldsOrder.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-reorder-fields/CStructFieldsOrder.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-reorder-fields/CStructFieldsOrder.cpp (added)
+++ clang-tools-extra/trunk/test/clang-reorder-fields/CStructFieldsOrder.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,16 @@
+// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order z,w,y,x %s -- | FileCheck %s
+
+namespace bar {
+struct Foo {
+ const int* x; // CHECK: {{^ double z;}}
+ int y; // CHECK-NEXT: {{^ int w;}}
+ double z; // CHECK-NEXT: {{^ int y;}}
+ int w; // CHECK-NEXT: {{^ const int\* x}}
+};
+} // end namespace bar
+
+int main() {
+ const int x = 13;
+ bar::Foo foo = { &x, 0, 1.29, 17 }; // CHECK: {{^ bar::Foo foo = { 1.29, 17, 0, &x };}}
+ return 0;
+}
Added: clang-tools-extra/trunk/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp (added)
+++ clang-tools-extra/trunk/test/clang-reorder-fields/ClassDifferentFieldsAccesses.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,16 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order z,y,x %s -- | FileCheck %s
+
+// The order of fields should not change.
+class Foo {
+public:
+ int x; // CHECK: {{^ int x;}}
+
+private:
+ int y; // CHECK: {{^ int y;}}
+ int z; // CHECK-NEXT: {{^ int z;}}
+};
+
+int main() {
+ Foo foo;
+ return 0;
+}
Added: clang-tools-extra/trunk/test/clang-reorder-fields/ClassMixedInitialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-reorder-fields/ClassMixedInitialization.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-reorder-fields/ClassMixedInitialization.cpp (added)
+++ clang-tools-extra/trunk/test/clang-reorder-fields/ClassMixedInitialization.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,24 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order e,x,pi,s2,s1 %s -- -std=c++11 | FileCheck %s
+
+class Foo {
+public:
+ Foo();
+
+private:
+ int x; // CHECK: {{^ double e = 2.71;}}
+ const char *s1; // CHECK-NEXT: {{^ int x;}}
+ const char *s2; // CHECK-NEXT: {{^ double pi = 3.14;}}
+ double pi = 3.14; // CHECK-NEXT: {{^ const char \*s2;}}
+ double e = 2.71; // CHECK-NEXT: {{^ const char \*s1;}}
+};
+
+Foo::Foo():
+ x(12), // CHECK: {{^ x\(12\)}},
+ s1("abc"), // CHECK-NEXT: {{^ s2\("def"\)}},
+ s2("def") // CHECK-NEXT: {{^ s1\("abc"\)}}
+{}
+
+int main() {
+ Foo foo;
+ return 0;
+}
Added: clang-tools-extra/trunk/test/clang-reorder-fields/ClassSimpleCtor.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-reorder-fields/ClassSimpleCtor.cpp?rev=280456&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-reorder-fields/ClassSimpleCtor.cpp (added)
+++ clang-tools-extra/trunk/test/clang-reorder-fields/ClassSimpleCtor.cpp Thu Sep 1 21:56:07 2016
@@ -0,0 +1,24 @@
+// RUN: clang-reorder-fields -record-name Foo -fields-order s1,x,z,s2 %s -- | FileCheck %s
+
+class Foo {
+public:
+ Foo();
+
+private:
+ int x; // CHECK: {{^ const char \*s1;}}
+ const char *s1; // CHECK-NEXT: {{^ int x;}}
+ const char *s2; // CHECK-NEXT: {{^ double z;}}
+ double z; // CHECK-NEXT: {{^ const char \*s2;}}
+};
+
+Foo::Foo():
+ x(12), // CHECK: {{^ s1\("abc"\),}}
+ s1("abc"), // CHECK-NEXT: {{^ x\(12\),}}
+ s2("def"), // CHECK-NEXT: {{^ z\(3.14\),}}
+ z(3.14) // CHECK-NEXT: {{^ s2\("def"\)}}
+{}
+
+int main() {
+ Foo foo;
+ return 0;
+}
More information about the cfe-commits
mailing list