summaryrefslogtreecommitdiffstats
path: root/clang-reorder-fields
diff options
context:
space:
mode:
authorAlexander Shaposhnikov <shal1t712@gmail.com>2017-07-20 21:41:20 +0000
committerAlexander Shaposhnikov <shal1t712@gmail.com>2017-07-20 21:41:20 +0000
commitcf934dc2a91f6af8f6ed9c36ce5e3188d509a1c9 (patch)
tree847b3ab012cd90e8725c026f4359a1db3f32e35e /clang-reorder-fields
parent70ded02647f48afe3ebbd3eff4c1a79b68f379f9 (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.cpp31
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))