1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
//===----------------------------------------------------------------------===//
//
// Copyright (c) 2012, 2015 The University of Utah
// All rights reserved.
//
// This file is distributed under the University of Illinois Open Source
// License. See the file COPYING for details.
//
//===----------------------------------------------------------------------===//
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include "MoveFunctionBody.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/SourceManager.h"
#include "TransformationManager.h"
using namespace clang;
static const char *DescriptionMsg =
"Move function body towards its declaration. \
Note that this pass would generate incompilable code. \n";
static RegisterTransformation<MoveFunctionBody>
Trans("move-function-body", DescriptionMsg);
void MoveFunctionBody::Initialize(ASTContext &context)
{
Transformation::Initialize(context);
}
bool MoveFunctionBody::HandleTopLevelDecl(DeclGroupRef D)
{
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
FunctionDecl *FD = dyn_cast<FunctionDecl>(*I);
if (!FD || isInIncludedFile(FD)) {
PrevFunctionDecl = NULL;
continue;
}
FunctionDecl *CanonicalFD = FD->getCanonicalDecl();
if (FD->isThisDeclarationADefinition()) {
FunctionDecl *FDDecl = AllValidFunctionDecls[CanonicalFD];
if (!FDDecl) {
PrevFunctionDecl = NULL;
continue;
}
// Declaration and Definition are next to each other
if (PrevFunctionDecl) {
FunctionDecl *CanonicalPrevFD = PrevFunctionDecl->getCanonicalDecl();
if (CanonicalFD == CanonicalPrevFD) {
PrevFunctionDecl = NULL;
continue;
}
}
FuncDeclToFuncDef[FDDecl] = FD;
}
PrevFunctionDecl = FD;
// We only need the first FunctionDecl
if (AllValidFunctionDecls[CanonicalFD])
continue;
AllValidFunctionDecls[CanonicalFD] = FD;
}
return true;
}
void MoveFunctionBody::HandleTranslationUnit(ASTContext &Ctx)
{
doAnalysis();
if (QueryInstanceOnly)
return;
if (TransformationCounter > ValidInstanceNum) {
TransError = TransMaxInstanceError;
return;
}
Ctx.getDiagnostics().setSuppressAllDiagnostics(false);
TransAssert(TheFunctionDecl && "NULL TheFunctionDecl!");
TransAssert(!TheFunctionDecl->isThisDeclarationADefinition() &&
"Invalid Function Declaration!");
TransAssert(TheFunctionDef && "NULL TheFunctionDef!");
TransAssert(TheFunctionDef->isThisDeclarationADefinition() &&
"Invalid Function Definition!");
doRewriting();
if (Ctx.getDiagnostics().hasErrorOccurred() ||
Ctx.getDiagnostics().hasFatalErrorOccurred())
TransError = TransInternalError;
}
void MoveFunctionBody::doAnalysis(void)
{
for (FuncDeclToFuncDeclMap::iterator I = FuncDeclToFuncDef.begin(),
E = FuncDeclToFuncDef.end(); I != E; ++I) {
ValidInstanceNum++;
if (ValidInstanceNum == TransformationCounter) {
TheFunctionDecl = (*I).first;
TheFunctionDef = (*I).second;
}
}
}
void MoveFunctionBody::doRewriting(void)
{
std::string FuncDefStr;
RewriteHelper->getFunctionDefStrAndRemove(TheFunctionDef, FuncDefStr);
RewriteHelper->addStringAfterFuncDecl(TheFunctionDecl, FuncDefStr);
}
MoveFunctionBody::~MoveFunctionBody(void)
{
// Nothing to do
}
|