Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

collection of fixes and cleanup #18

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
cmake_minimum_required(VERSION 3.1)
add_subdirectory(src)
cmake_minimum_required(VERSION 3.16)
set(CMAKE_UNITY_BUILD TRUE)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 8)
add_compile_options($<$<CONFIG:Debug>:-Og> -gsplit-dwarf)

add_subdirectory(src)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Then run cmake and make (adapt your paths)
* As a binary: replace the moc provided by Qt by the one which is in src/moc

* As a clang plugin: Tell your build system not to run moc, and add this to the CXXFLAGS
-Xclang -load -Xclang /path/to/src/libmocng_plugin.so -Xclang -add-plugin -Xclang moc
`-fplugin=/path/to/src/libmocng_plugin.so`

## Differences with upstream moc

Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
Find_Package(Clang REQUIRED CONFIG HINTS "${LLVM_INSTALL_PREFIX}/lib/cmake/clang")
message(STATUS "Found Clang in ${CLANG_INSTALL_PREFIX}")

set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD 14)

SET(common_srcs mocng.cpp generator.cpp propertyparser.cpp mocppcallbacks.cpp mocastconsumer.cpp
qbjs.cpp clangversionabstraction.cpp workaroundtests.cpp)
Expand Down
20 changes: 16 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct MocDiagConsumer : clang::DiagnosticConsumer {



struct MocNGASTConsumer : public MocASTConsumer {
struct MocNGASTConsumer final : public MocASTConsumer {
std::string InFile;
MocNGASTConsumer(clang::CompilerInstance& ci, llvm::StringRef InFile) : MocASTConsumer(ci), InFile(InFile) { }

Expand Down Expand Up @@ -273,7 +273,7 @@ class MocAction : public clang::ASTFrontendAction {

public:
// CHECK
virtual bool hasCodeCompletionSupport() const { return true; }
virtual bool hasCodeCompletionSupport() const override { return true; }
};

static void showVersion(bool /*Long*/) {
Expand Down Expand Up @@ -448,7 +448,13 @@ int main(int argc, const char **argv)

if (PreprocessorOnly) {
Argv.push_back("-P");
clang::tooling::ToolInvocation Inv(Argv, new clang::PrintPreprocessedAction, &FM);
clang::tooling::ToolInvocation Inv(Argv,
#if CLANG_VERSION_MAJOR >= 10
std::make_unique<clang::PrintPreprocessedAction>(),
#else
new clang::PrintPreprocessedAction,
#endif
&FM);
return !Inv.run();
}

Expand All @@ -462,7 +468,13 @@ int main(int argc, const char **argv)
Argv.push_back("QtCore/qobject.h");
}

clang::tooling::ToolInvocation Inv(Argv, new MocAction, &FM);
clang::tooling::ToolInvocation Inv(Argv,
#if CLANG_VERSION_MAJOR >= 10
std::make_unique<MocAction>(),
#else
new MocAction,
#endif
&FM);

const EmbeddedFile *f = EmbeddedFiles;
while (f->filename) {
Expand Down
2 changes: 1 addition & 1 deletion src/mocastconsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void MocASTConsumer::Initialize(clang::ASTContext& Ctx) {

// We will enable this when we require Qt >= 5.6.1 and libclang >= 3.8
// Then we will be able to get rid of qobjectdefs-injected
#if 0
#if 1
std::string qtPredefinesBuffer;
llvm::raw_string_ostream qtPredefines(qtPredefinesBuffer);
clang::MacroBuilder builder(qtPredefines);
Expand Down
4 changes: 2 additions & 2 deletions src/mocastconsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class MocASTConsumer : public clang::ASTConsumer
MocASTConsumer(clang::CompilerInstance &ci) :ci(ci)
{ }

void Initialize(clang::ASTContext& Ctx) override;
void HandleTagDeclDefinition(clang::TagDecl* D) override;
void Initialize(clang::ASTContext &Ctx) final;
void HandleTagDeclDefinition(clang::TagDecl* D) final;
bool HandleTopLevelDecl(clang::DeclGroupRef D) override;

virtual bool shouldParseDecl(clang::Decl *D) { return true; }
Expand Down
50 changes: 32 additions & 18 deletions src/mocng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,33 @@ static void parsePluginMetaData(ClassDef &Def, clang::Expr *Content, clang::Sema
else {
llvm::StringRef Filename = Literal.GetString();
const clang::DirectoryLookup *CurDir;
const clang::FileEntry *File = PP.LookupFile(
Val->getSourceRange().getBegin(),
Filename, false, nullptr,
#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>5
nullptr,
#endif
CurDir, nullptr, nullptr, nullptr
#if CLANG_VERSION_MAJOR >= 5
, nullptr
#if CLANG_VERSION_MAJOR < 10
const clang::FileEntry *File =
#else
const clang::Optional<clang::FileEntryRef> fileRef
{
#endif
#if CLANG_VERSION_MAJOR >= 9
, nullptr
PP.LookupFile(
Val->getSourceRange().getBegin(),
Filename, false, nullptr,
#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>5
nullptr,
#endif
CurDir, nullptr, nullptr, nullptr
#if CLANG_VERSION_MAJOR >= 5
, nullptr
#endif
#if CLANG_VERSION_MAJOR >= 9
, nullptr
#endif
)
#if CLANG_VERSION_MAJOR >= 10
};

const clang::FileEntry *File = fileRef ? &fileRef->getFileEntry() : nullptr;
#else
;
#endif
);

if (!File) {
PP.getDiagnostics().Report(GetFromLiteral(StrToks.front(), Val, PP), clang::diag::err_pp_file_not_found)
Expand Down Expand Up @@ -340,8 +353,9 @@ static void parseClassInfo(BaseDef &Def, clang::Expr *SubExp, clang::Preprocesso

static bool IsAnnotationStaticAssert(clang::Decl *Decl, llvm::StringRef *Key, clang::Expr **SubExp) {
if (clang::StaticAssertDecl *S = llvm::dyn_cast<clang::StaticAssertDecl>(Decl)) {
if (auto *E = llvm::dyn_cast<clang::UnaryExprOrTypeTraitExpr>(S->getAssertExpr()))
if (clang::ParenExpr *PE = llvm::dyn_cast<clang::ParenExpr>(E->getArgumentExpr()))
if (auto *Cast = llvm::dyn_cast<clang::ImplicitCastExpr>(S->getAssertExpr()))
if (auto *E = llvm::dyn_cast<clang::UnaryExprOrTypeTraitExpr>(Cast->getSubExpr()))
if (clang::ParenExpr *PE = llvm::dyn_cast<clang::ParenExpr>(E->getArgumentExpr()))
{
*Key = S->getMessage()->getString();
*SubExp = PE->getSubExpr();
Expand All @@ -357,10 +371,10 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema)
ClassDef Def;
Def.Record = RD;

for (auto it = RD->decls_begin(); it != RD->decls_end(); ++it) {
for (auto decl : RD->decls()) {
llvm::StringRef key;
clang::Expr *SubExp;
if (IsAnnotationStaticAssert(*it, &key, &SubExp)) {
if (IsAnnotationStaticAssert(decl, &key, &SubExp)) {
if (key == "qt_property") {
clang::StringLiteral *Val = llvm::dyn_cast<clang::StringLiteral>(SubExp);
if (Val) {
Expand All @@ -371,7 +385,7 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema)
Def.Properties.push_back(Parser.parseProperty());
Def.addExtra(Parser.Extra);
} else {
PP.getDiagnostics().Report((*it)->getLocation(),
PP.getDiagnostics().Report(decl->getLocation(),
PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
"Invalid Q_PROPERTY annotation"));
}
Expand Down Expand Up @@ -423,7 +437,7 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema)
parsePluginMetaData(Def, SubExp, Sema);
HasPlugin = true;
}
} else if (clang::CXXMethodDecl *M = llvm::dyn_cast<clang::CXXMethodDecl>(*it)) {
} else if (clang::CXXMethodDecl *M = llvm::dyn_cast<clang::CXXMethodDecl>(decl)) {
for (auto attr_it = M->specific_attr_begin<clang::AnnotateAttr>();
attr_it != M->specific_attr_end<clang::AnnotateAttr>();
++attr_it) {
Expand Down
4 changes: 3 additions & 1 deletion src/mocppcallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
#include "clangversionabstraction.h"

void MocPPCallbacks::InjectQObjectDefs(clang::SourceLocation Loc) {
#include "qobjectdefs-injected.h"
#if 0
#include "qobjectdefs-injected.h"
auto Buf = maybe_unique(llvm::MemoryBuffer::getMemBuffer(Injected, "qobjectdefs-injected.moc"));
Loc = PP.getSourceManager().getFileLoc(Loc);
PP.EnterSourceFile( CreateFileIDForMemBuffer(PP, Buf, Loc), nullptr, Loc);
#endif
}

void MocPPCallbacks::EnterMainFile(llvm::StringRef Name)
Expand Down
4 changes: 2 additions & 2 deletions src/mocppcallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once
#include <clang/Lex/Preprocessor.h>
#include <clang/Basic/Version.h>
#include <set>

class MocPPCallbacks : public clang::PPCallbacks {
class MocPPCallbacks final : public clang::PPCallbacks {
clang::Preprocessor &PP;

bool IncludeNotFoundSupressed = false;
Expand Down
26 changes: 15 additions & 11 deletions src/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static bool IsQtInternal(const clang::CXXMethodDecl *MD) {
return (Name.startswith("qt_") || Name == "metaObject");
}

class MocPluginASTConsumer : public MocASTConsumer {
class MocPluginASTConsumer final : public MocASTConsumer {
bool done = false;

bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
Expand Down Expand Up @@ -125,33 +125,33 @@ class MocPluginASTConsumer : public MocASTConsumer {
Key = nullptr;

if (!Key) {
for (auto it = RD->method_begin(); it != RD->method_end(); ++it ) {
for (auto Method : RD->methods()) {

if (Key && !it->isVirtual())
if (Key && !Method->isVirtual())
continue;

if (it->isPure() || it->isImplicit() || it->hasInlineBody()
|| it->isInlineSpecified() || !it->isUserProvided() )
if (Method->isPure() || Method->isImplicit() || Method->hasInlineBody()
|| Method->isInlineSpecified() || !Method->isUserProvided() )
continue;

const clang::FunctionDecl *Def;
if (it->hasBody(Def) && Def->isInlineSpecified())
if (Method->hasBody(Def) && Def->isInlineSpecified())
continue;

if (IsQtInternal(*it))
if (IsQtInternal(Method))
continue;

/* if (Key->isFunctionTemplateSpecialization())
continue; */

if (std::any_of(it->specific_attr_begin<clang::AnnotateAttr>(),
it->specific_attr_end<clang::AnnotateAttr>(),
if (std::any_of(Method->specific_attr_begin<clang::AnnotateAttr>(),
Method->specific_attr_end<clang::AnnotateAttr>(),
[](clang::AnnotateAttr *A) {
return A->getAnnotation() == "qt_signal";
}))
continue;

Key = *it;
Key = Method;
if (Key->isVirtual())
break;
}
Expand Down Expand Up @@ -186,7 +186,7 @@ class MocPluginASTConsumer : public MocASTConsumer {
MocPluginASTConsumer(clang::CompilerInstance& ci) : MocASTConsumer(ci) {}
};

class MocPluginAction : public clang::PluginASTAction {
class MocPluginAction final : public clang::PluginASTAction {
protected:
#if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR <= 5
clang::ASTConsumer *
Expand All @@ -199,6 +199,10 @@ class MocPluginAction : public clang::PluginASTAction {
bool ParseArgs(const clang::CompilerInstance& CI, const std::vector< std::string >& arg) override {
return true;
}

ActionType getActionType() override {
return AddAfterMainAction;
}
};


Expand Down