Skip to content

Instantly share code, notes, and snippets.

@kuhar
Created January 17, 2017 13:49
Show Gist options
  • Save kuhar/fd205c2f38e1baa4331e70dd5cb45b42 to your computer and use it in GitHub Desktop.
Save kuhar/fd205c2f38e1baa4331e70dd5cb45b42 to your computer and use it in GitHub Desktop.
replace_ctors_repro
cmake_minimum_required(VERSION 3.4)
project(repro)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z -fPIC -fno-exceptions -fno-rtti -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -Werror=date-time")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=undefined")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
include_directories(~/Projects/llvm/include
~/Projects/llvm/tools/clang/include
~/Projects/build_llvm/include
~/Projects/build_llvm/tools/clang/include)
link_directories(~/Projects/build_llvm/lib)
add_library(repro SHARED repro.cpp)
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Sema/Sema.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace clang;
namespace {
class Repro : public ASTConsumer {
CompilerInstance &Instance;
std::set<std::string> ParsedTemplates;
public:
Repro(CompilerInstance &Instance, std::set<std::string> ParsedTemplates)
: Instance(Instance), ParsedTemplates(ParsedTemplates) {}
bool HandleTopLevelDecl(DeclGroupRef DG) override {
for (auto it = DG.begin(), e = DG.end(); it != e; ++it) {
if (auto *VD = dyn_cast<VarDecl>(*it)) {
if (VD->getName() == "c")
ChangeCtor(VD);
}
}
return true;
}
private:
void ChangeCtor(VarDecl *VD) {
VD->dump();
auto &Sema = Instance.getSema();
auto &Context = Sema.getASTContext();
auto Loc = VD->getSourceRange().getBegin();
auto VarQT = VD->getType();
auto *Zero = clang::IntegerLiteral::Create(Context, llvm::APInt(32, 0),
Context.IntTy, Loc);
auto *RDecl = VarQT->getAsCXXRecordDecl();
CXXConstructorDecl *Ctor = nullptr;
for (auto *CD : RDecl->ctors())
if (CD->getNumParams() == 2)
Ctor = CD;
Expr *Params[] = {Zero, Zero};
auto *ConstructExpr = CXXConstructExpr::Create(
Context, VarQT, Loc, Ctor, false, Params, true, true, false, false,
CXXConstructExpr::CK_Complete, VD->getSourceRange());
ConstructExpr->dump();
VD->setInit(ConstructExpr);
VD->dump();
}
};
class ReproAction : public PluginASTAction {
std::set<std::string> ParsedTemplates;
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef) override {
return llvm::make_unique<Repro>(CI, ParsedTemplates);
}
bool ParseArgs(const CompilerInstance &,
const std::vector<std::string> &) override {
return true;
}
ActionType getActionType() override { return AddBeforeMainAction; }
};
}
static FrontendPluginRegistry::Add<ReproAction> X("repro", "");
template <typename> struct C {
C() {}
C(int, int) {}
};
C<void> c = {};
//C<void> d = {0, 0};
int main() {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment