From 30fca0af955f77eebe14eeef96ca4c7c043c2f9a Mon Sep 17 00:00:00 2001 From: Manoel Roemmer Date: Fri, 8 Feb 2019 17:05:56 +0100 Subject: [PATCH] Fix problems with some complex macros When two decls get generated by the same macro, TargetCode compared the spelling location of their generated source fragments and not their expanded location. This resulted in TargetCode not adding more than once function generated from a macro. --- clang/tools/sotoc/src/Debug.h | 2 +- clang/tools/sotoc/src/DeclResolver.cpp | 6 +++++- clang/tools/sotoc/src/TargetCode.cpp | 4 ++-- clang/tools/sotoc/src/TargetCodeFragment.cpp | 19 +++++++++++++++++-- clang/tools/sotoc/src/TargetCodeFragment.h | 5 +++++ clang/tools/sotoc/src/main.cpp | 1 + 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/clang/tools/sotoc/src/Debug.h b/clang/tools/sotoc/src/Debug.h index 4fee2f6cb8dc96..896311e202dd5f 100644 --- a/clang/tools/sotoc/src/Debug.h +++ b/clang/tools/sotoc/src/Debug.h @@ -23,7 +23,7 @@ extern int SotocDebugLevel; #define DEBUGP(...) \ do { \ if (SotocDebugLevel > 0) { \ - llvm::errs() << "Sotoc: " << llvm::formatv(__VA_ARGS__); \ + llvm::errs() << "Sotoc: " << __VA_ARGS__; \ llvm::errs() << "\n"; \ } \ } while (false) diff --git a/clang/tools/sotoc/src/DeclResolver.cpp b/clang/tools/sotoc/src/DeclResolver.cpp index 8b8b3bced60c60..f736af973e3338 100644 --- a/clang/tools/sotoc/src/DeclResolver.cpp +++ b/clang/tools/sotoc/src/DeclResolver.cpp @@ -65,6 +65,8 @@ void DeclResolver::addDecl(clang::Decl *D) { return; } + DEBUGPDECL(D, "Add declaration to resolver: "); + std::unordered_set UnresolvedDecls; UnresolvedDecls.insert(D); @@ -161,9 +163,11 @@ void DeclResolver::orderAndAddFragments(TargetCode &TC) { if (!AllDecls.at(orderStack.top()).IsFromSystemHeader) { auto codeDecl = std::make_shared(orderStack.top()); + DEBUGPDECL(orderStack.top(), "Generating Fragment for Decl: "); // TODO: this wont hurt but is not always necessary codeDecl->NeedsSemicolon = true; - TC.addCodeFragmentFront(codeDecl); + bool added = TC.addCodeFragmentFront(codeDecl); + DEBUGP("Decl was a duplicate: " << !added); } orderStack.pop(); } diff --git a/clang/tools/sotoc/src/TargetCode.cpp b/clang/tools/sotoc/src/TargetCode.cpp index ab5a7ed123b808..10076f047264c2 100644 --- a/clang/tools/sotoc/src/TargetCode.cpp +++ b/clang/tools/sotoc/src/TargetCode.cpp @@ -75,7 +75,7 @@ void TargetCode::generateCode(llvm::raw_ostream &Out) { // This is a workaround, since "Decl::print" includes "pragma omp declare". if (PrettyCode != "") - TargetCodeRewriter.ReplaceText(Frag->getInnerRange(), PrettyCode); + TargetCodeRewriter.ReplaceText(Frag->getSpellingRange(), PrettyCode); if (TCR) { generateFunctionPrologue(TCR); @@ -85,7 +85,7 @@ void TargetCode::generateCode(llvm::raw_ostream &Out) { generateFunctionEpilogue(TCR); } Out << "\n"; - Out << TargetCodeRewriter.getRewrittenText(Frag->getInnerRange()); + Out << TargetCodeRewriter.getRewrittenText(Frag->getSpellingRange()); if (Frag->NeedsSemicolon) { Out << ";"; diff --git a/clang/tools/sotoc/src/TargetCodeFragment.cpp b/clang/tools/sotoc/src/TargetCodeFragment.cpp index 6a4b70d552053a..4e40fcfd49356e 100644 --- a/clang/tools/sotoc/src/TargetCodeFragment.cpp +++ b/clang/tools/sotoc/src/TargetCodeFragment.cpp @@ -156,6 +156,13 @@ clang::SourceRange TargetCodeRegion::getRealRange() { return CapturedStmtNode->getSourceRange(); } +clang::SourceRange TargetCodeRegion::getSpellingRange() { + auto &SM = CapturedStmtNode->getCapturedDecl()->getASTContext().getSourceManager(); + auto InnerRange = getInnerRange(); + return clang::SourceRange(SM.getSpellingLoc(InnerRange.getBegin()), + SM.getSpellingLoc(InnerRange.getEnd())); +} + clang::SourceRange TargetCodeRegion::getInnerRange() { auto InnerLocStart = getStartLoc(); auto InnerLocEnd = getEndLoc(); @@ -428,9 +435,17 @@ std::string TargetCodeRegion::PrintPretty() { clang::SourceRange TargetCodeDecl::getRealRange() { // return DeclNode->getSourceRange(); // return DeclNode->getSourceRange(); + //auto &SM = DeclNode->getASTContext().getSourceManager(); + //return clang::SourceRange(SM.getSpellingLoc(DeclNode->getBeginLoc()), + // SM.getSpellingLoc(DeclNode->getEndLoc())); + return DeclNode->getSourceRange(); +} + +clang::SourceRange TargetCodeDecl::getSpellingRange() { auto &SM = DeclNode->getASTContext().getSourceManager(); - return clang::SourceRange(SM.getSpellingLoc(DeclNode->getBeginLoc()), - SM.getSpellingLoc(DeclNode->getEndLoc())); + auto InnerRange = getInnerRange(); + return clang::SourceRange(SM.getSpellingLoc(InnerRange.getBegin()), + SM.getSpellingLoc(InnerRange.getEnd())); } std::string TargetCodeDecl::PrintPretty() { diff --git a/clang/tools/sotoc/src/TargetCodeFragment.h b/clang/tools/sotoc/src/TargetCodeFragment.h index 08f45d586ed83c..1066599c7c1810 100644 --- a/clang/tools/sotoc/src/TargetCodeFragment.h +++ b/clang/tools/sotoc/src/TargetCodeFragment.h @@ -83,6 +83,9 @@ class TargetCodeFragment { /// Gets the 'inner' source range. This can differ for target regions from the /// source range. virtual clang::SourceRange getInnerRange() { return getRealRange(); }; + /// Get the spelling source range. That is the range without macro + /// expansions. + virtual clang::SourceRange getSpellingRange() = 0; /// Accessor to TargetCodeKind clang::OpenMPDirectiveKind getTargetCodeKind() { return TargetCodeKind; }; }; @@ -140,6 +143,7 @@ class TargetCodeRegion : public TargetCodeFragment { virtual std::string PrintPretty() override; clang::SourceRange getRealRange() override; clang::SourceRange getInnerRange() override; + clang::SourceRange getSpellingRange() override; /// Returns a source location at the start of a pragma in the captured /// statment. clang::SourceLocation getStartLoc(); @@ -174,4 +178,5 @@ class TargetCodeDecl : public TargetCodeFragment { virtual std::string PrintPretty() override; clang::SourceRange getRealRange() override; + clang::SourceRange getSpellingRange() override; }; diff --git a/clang/tools/sotoc/src/main.cpp b/clang/tools/sotoc/src/main.cpp index 398e791f4c4627..a1cc2ab96cb773 100644 --- a/clang/tools/sotoc/src/main.cpp +++ b/clang/tools/sotoc/src/main.cpp @@ -72,6 +72,7 @@ class SourceTransformAction : public clang::ASTFrontendAction { // std::error_code error_code; // llvm::raw_fd_ostream outFile("output.txt", error_code, // llvm::sys::fs::F_Append); + DEBUGP("Generating CodeĀ§"); Code->generateCode(llvm::outs()); // outFile.close(); delete Code;