Skip to content

Commit

Permalink
Major rewrite to catch even more statements.
Browse files Browse the repository at this point in the history
Initially a lot of AST matchers where involved to match certain
hand-picked statements (like range-based for loops, auto or
if-statements). With the evolution C++ Insights this became a burden as
all the matchers needed to be locked against each other. Failing here
lead to a couple of issues. Another drawback is, that there are code
parts which remained untouched.

Now, this patch removes most of these AST matchers and instead matches
FunctionsDecl's. This should rewrite all functions, classes and function
/ class templates. With that C++ Insights should have a much broader
rewrite coverage. However, there is another disadvantage. The code does
look less beautiful as some newlines are missing. clang-format can
correct these on local installations so for now it is accepted.
  • Loading branch information
Andreas Fertig committed Jul 14, 2018
1 parent c64c1f2 commit b6c1a54
Show file tree
Hide file tree
Showing 215 changed files with 4,844 additions and 4,040 deletions.
80 changes: 2 additions & 78 deletions AutoStmtHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,17 @@ using namespace clang;
using namespace clang::ast_matchers;
//-----------------------------------------------------------------------------

#include "clang/Basic/Version.h"

namespace clang::insights {

#if CLANG_VERSION_MAJOR < 7
AST_MATCHER(FunctionDecl, hasTrailingReturn)
{
(void)Finder;
(void)Builder;

if(const auto* F = Node.getType()->getAs<FunctionProtoType>())
return F->hasTrailingReturn();
return false;
}
#endif

AutoStmtHandler::AutoStmtHandler(Rewriter& rewrite, MatchFinder& matcher)
: InsightsBase(rewrite)
{
matcher.addMatcher(varDecl(unless(anyOf(isExpansionInSystemHeader(),
isMacroOrInvalidLocation(),
/* don't substitute lambdas */
/* exclude rangeStateFor and if with init for now*/
hasAncestor(cxxForRangeStmt()),
decompositionDecl(),
hasAncestor(lambdaExpr()),
/* don't replace auto in templates */
isTemplate,
hasAncestor(switchStmt()),
hasAncestor(ifStmt()))),
hasAncestor(functionDecl()))),
anyOf(/* auto */
hasType(autoType().bind("autoType")),
hasType(qualType(hasDescendant(autoType().bind("autoType")))),
Expand All @@ -54,69 +35,12 @@ AutoStmtHandler::AutoStmtHandler(Rewriter& rewrite, MatchFinder& matcher)
hasType(qualType(hasDescendant(decltypeType().bind("dt"))))))
.bind("autoDecl"),
this);

matcher.addMatcher(functionDecl(allOf(hasTrailingReturn(),
unless(anyOf(isExpansionInSystemHeader(),
/* don't replace auto in templates */
isTemplate,
returns(decltypeType().bind("dt")),
hasParent(cxxRecordDecl(isLambda()))))))
.bind("funcDecl"),
this);

matcher.addMatcher(
functionDecl(
allOf(returns(autoType()),
unless(anyOf(isExpansionInSystemHeader(), isTemplate, hasParent(cxxRecordDecl(isLambda()))))))
.bind("funcDecl"),
this);
}
//-----------------------------------------------------------------------------

void AutoStmtHandler::run(const MatchFinder::MatchResult& result)
{
if(const auto* funcDecl = result.Nodes.getNodeAs<FunctionDecl>("funcDecl")) {
const bool hasTrailingReturn = [&]() {
if(const auto* functionProtoType = funcDecl->getType()->getAs<FunctionProtoType>()) {
return functionProtoType->hasTrailingReturn();
}

return false;
}();

// XXX hack to remove trailing return type -> xxx
if(hasTrailingReturn) {

// DPrint("trialing\n");
if(const Stmt* body = funcDecl->getBody()) {
OutputFormatHelper outputFormatHelper{};
GenerateFunctionPrototype(outputFormatHelper, *funcDecl);
// DPrint("func: %s\n", outputFormatHelper.GetString());

const SourceLocation bodyLoc{body->getLocStart()};
const SourceRange trailingReturnRange{funcDecl->getSourceRange().getBegin(),
bodyLoc.getLocWithOffset(-1)};

mRewrite.ReplaceText(trailingReturnRange, outputFormatHelper.GetString());
return;
}
}

// decltype(auto) Function(params) { }
// ^ ^ ^
// 1 2 3
// the getLocStart starts at (1) end ends at (3). The getLocation in the other hand starts at (2) and
// ends at (3)
const SourceRange sr{funcDecl->getLocStart(), funcDecl->getLocation().getLocWithOffset(-1)};

const std::string fqn{StrCat((funcDecl->isConstexpr() ? kwConstExprSpace : ""),
(funcDecl->isInlined() ? kwInlineSpace : ""),
GetName(GetDesugarReturnType(*funcDecl)))};

mRewrite.ReplaceText(sr /*FuncDecl->getReturnTypeSourceRange()*/, fqn);

return;
} else if(const auto* autoDecl = result.Nodes.getNodeAs<VarDecl>("autoDecl")) {
if(const auto* autoDecl = result.Nodes.getNodeAs<VarDecl>("autoDecl")) {
const QualType type = [&]() {
if(const auto* declType = result.Nodes.getNodeAs<DecltypeType>("dt")) {
return declType->getUnderlyingType();
Expand Down
9 changes: 1 addition & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,23 +278,16 @@ endif(CCACHE_FOUND)
# name the executable and all source files
add_clang_executable(insights
AutoStmtHandler.cpp
ClassOperatorHandler.cpp
CodeGenerator.cpp
CommaOperatorHandler.cpp
CompilerGeneratedHandler.cpp
DPrint.cpp
IfStmtHandler.cpp
FunctionDeclHandler.cpp
ImplicitCastHandler.cpp
Insights.cpp
InsightsBase.cpp
InsightsHelpers.cpp
LambdaHandler.cpp
NRVOHandler.cpp
OutputFormatHelper.cpp
RangeForStmtHandler.cpp
StaticAssertHandler.cpp
StaticHandler.cpp
StdInitializerListHandler.cpp
StructuredBindingsHandler.cpp
TemplateHandler.cpp
UserDefinedLiteralHandler.cpp
Expand Down
127 changes: 0 additions & 127 deletions ClassOperatorHandler.cpp

This file was deleted.

35 changes: 0 additions & 35 deletions ClassOperatorHandler.h

This file was deleted.

Loading

0 comments on commit b6c1a54

Please sign in to comment.