diff options
author | Alexander Shaposhnikov <shal1t712@gmail.com> | 2017-07-20 21:41:20 +0000 |
---|---|---|
committer | Alexander Shaposhnikov <shal1t712@gmail.com> | 2017-07-20 21:41:20 +0000 |
commit | cf934dc2a91f6af8f6ed9c36ce5e3188d509a1c9 (patch) | |
tree | 847b3ab012cd90e8725c026f4359a1db3f32e35e /clang-reorder-fields | |
parent | 70ded02647f48afe3ebbd3eff4c1a79b68f379f9 (diff) |
[clang-tools-extra] Add support for plain C structs in clang-reorder-fields
This diff updates the tool clang-reorder-fields
to enable reordering of fields of plain C structs.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D35329
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@308678 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-reorder-fields')
-rw-r--r-- | clang-reorder-fields/ReorderFieldsAction.cpp | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/clang-reorder-fields/ReorderFieldsAction.cpp b/clang-reorder-fields/ReorderFieldsAction.cpp index 1996380a..ae22b346 100644 --- a/clang-reorder-fields/ReorderFieldsAction.cpp +++ b/clang-reorder-fields/ReorderFieldsAction.cpp @@ -32,10 +32,10 @@ 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) { +static const RecordDecl *findDefinition(StringRef RecordName, + ASTContext &Context) { auto Results = match( - recordDecl(hasName(RecordName), isDefinition()).bind("cxxRecordDecl"), + recordDecl(hasName(RecordName), isDefinition()).bind("recordDecl"), Context); if (Results.empty()) { llvm::errs() << "Definition of " << RecordName << " not found\n"; @@ -46,14 +46,14 @@ static const CXXRecordDecl *findDefinition(StringRef RecordName, << " is ambiguous, several definitions found\n"; return nullptr; } - return selectFirst<CXXRecordDecl>("cxxRecordDecl", Results); + return selectFirst<RecordDecl>("recordDecl", 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, +getNewFieldsOrder(const RecordDecl *Definition, ArrayRef<std::string> DesiredFieldsOrder) { assert(Definition && "Definition is null"); @@ -97,7 +97,7 @@ addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context, /// different accesses (public/protected/private) is not supported. /// \returns true on success. static bool reorderFieldsInDefinition( - const CXXRecordDecl *Definition, ArrayRef<unsigned> NewFieldsOrder, + const RecordDecl *Definition, ArrayRef<unsigned> NewFieldsOrder, const ASTContext &Context, std::map<std::string, tooling::Replacements> &Replacements) { assert(Definition && "Definition is null"); @@ -223,7 +223,7 @@ public: ReorderingConsumer &operator=(const ReorderingConsumer &) = delete; void HandleTranslationUnit(ASTContext &Context) override { - const CXXRecordDecl *RD = findDefinition(RecordName, Context); + const RecordDecl *RD = findDefinition(RecordName, Context); if (!RD) return; SmallVector<unsigned, 4> NewFieldsOrder = @@ -232,16 +232,21 @@ public: 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. + // CXXRD will be nullptr if C code (not C++) is being processed. + const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD); + if (CXXRD) + for (const auto *C : CXXRD->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 + // plain C structs or C++ 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()) + if (!CXXRD || CXXRD->isAggregate()) for (auto Result : match(initListExpr(hasType(equalsNode(RD))).bind("initListExpr"), Context)) |