From ba75f6ff375becf1496b801f5252942663a56c5f Mon Sep 17 00:00:00 2001 From: Alex Lin Date: Fri, 28 Oct 2016 13:21:21 -0500 Subject: [PATCH] ICG does not compile using llvm 3.9 #339 The call getRBraceLoc to find the ending source location of things is gone. Replaced it with getting the source range and get the end of that range. Also the way to get clang/llvm 3.9 to process c++11 code required some reordering of calls in main as well as adding some more features to be turned on. --- .../Interface_Code_Gen/ClassVisitor.cpp | 12 +- .../Interface_Code_Gen/EnumVisitor.cpp | 2 +- .../PrintFileContents10.cpp | 2 + .../TranslationUnitVisitor.cpp | 46 +++---- .../codegen/Interface_Code_Gen/main.cpp | 114 ++++++++++-------- .../codegen/Interface_Code_Gen/makefile | 3 +- 6 files changed, 99 insertions(+), 80 deletions(-) diff --git a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp index 4ab3af05..cf8f9d01 100644 --- a/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/ClassVisitor.cpp @@ -56,7 +56,7 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) { clang::RecordDecl * rd = crd->getDefinition() ; if ( rd != NULL ) { if ( rd->getAccess() == clang::AS_public ) { - if ( isInUserCode(ci , crd->getRBraceLoc(), hsd) ) { + if ( isInUserCode(ci , crd->getSourceRange().getEnd(), hsd) ) { CXXRecordVisitor embedded_cvis(ci , cs, hsd , pa, true) ; embedded_cvis.TraverseCXXRecordDecl(static_cast(d)) ; pa.printClass(embedded_cvis.get_class_data()) ; @@ -149,7 +149,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) { } // Return false to stop processing if this header file is excluded by one of many reasons. - std::string header_file_name = getFileName(ci , rec->getRBraceLoc(), hsd) ; + std::string header_file_name = getFileName(ci , rec->getSourceRange().getEnd(), hsd) ; char * rp = almostRealPath(header_file_name.c_str()) ; if ( rp == NULL || !hsd.isPathInUserDir(rp) || @@ -200,13 +200,13 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) { clang::RecordDecl * rd = rt->getDecl() ; //std::cout << " " << cval.getName() << " inherits from " << rd->getNameAsString() << "" << std::endl ; //rd->dump() ; std::cout << std::endl ; - if ( isInUserOrTrickCode(ci , rd->getRBraceLoc(), hsd) ) { + if ( isInUserOrTrickCode(ci , rd->getSourceRange().getEnd(), hsd) ) { const clang::ASTRecordLayout &record_layout = rec->getASTContext().getASTRecordLayout(rec); unsigned int inherit_class_offset ; inherit_class_offset = record_layout.getBaseClassOffset(llvm::cast(rd)).getQuantity() ; //std::cout << " inherit_class_offset = " << inherit_class_offset << "" << std::endl ; - //std::cout << " " << getFileName(ci , rd->getRBraceLoc(), hsd) << "" << std::endl ; + //std::cout << " " << getFileName(ci , rd->getSourceRange().getEnd(), hsd) << "" << std::endl ; CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, false) ; inherit_cvis.TraverseCXXRecordDecl(static_cast(rd)) ; cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(), @@ -248,7 +248,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) { //std::cout << " " << cval.getName() << " virtually inherits from " // << rd->getNameAsString() << "" << std::endl ; //rd->dump() ; std::cout << std::endl ; - if ( isInUserOrTrickCode(ci , rd->getRBraceLoc(), hsd) ) { + if ( isInUserOrTrickCode(ci , rd->getSourceRange().getEnd(), hsd) ) { const clang::ASTRecordLayout &record_layout = rec->getASTContext().getASTRecordLayout(rec); unsigned int inherit_class_offset ; @@ -257,7 +257,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) { inherit_class_offset = record_layout.getVBaseClassOffset(llvm::cast(rd)).getQuantity() ; //std::cout << " inherit_class_offset = " << inherit_class_offset << "" << std::endl ; - //std::cout << " " << getFileName(ci , rd->getRBraceLoc(), hsd) << "" << std::endl ; + //std::cout << " " << getFileName(ci , rd->getSourceRange().getEnd(), hsd) << "" << std::endl ; CXXRecordVisitor inherit_cvis(ci , cs, hsd , pa, false) ; inherit_cvis.TraverseCXXRecordDecl(static_cast(rd)) ; cval.addInheritedFieldDescriptions(inherit_cvis.get_class_data()->getFieldDescription(), inherit_class_offset, true) ; diff --git a/trick_source/codegen/Interface_Code_Gen/EnumVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/EnumVisitor.cpp index f99fc72c..31c3edc2 100644 --- a/trick_source/codegen/Interface_Code_Gen/EnumVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/EnumVisitor.cpp @@ -26,7 +26,7 @@ bool EnumVisitor::VisitType(clang::Type *t) { } bool EnumVisitor::VisitEnumDecl(clang::EnumDecl *ed) { - eval.setFileName(getFileName(ci , ed->getRBraceLoc(), hsd)) ; + eval.setFileName(getFileName(ci , ed->getSourceRange().getEnd(), hsd)) ; return true; } diff --git a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp index d28b7c32..b259e6f7 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintFileContents10.cpp @@ -300,6 +300,7 @@ void PrintFileContents10::print_init_attr_func( std::ostream & ostream , ClassVa ostream << " typedef " << cv->getName() << " " << cv->getMangledTypeName() << " ;\n\n" ; } +#if 0 if ( !global_compat15 and !cv->isCompat15()) { ostream << " if ( sizeof(" ; printNamespaces( ostream, cv , "::" ) ; @@ -314,6 +315,7 @@ void PrintFileContents10::print_init_attr_func( std::ostream & ostream , ClassVa ostream << cv->getName() << ") - " << cv->getSize() << ") , \"" << cv->getFileName() << "\")) ;\n" ; ostream << " }\n" ; } +#endif unsigned int ii = 0 ; for ( fit = cv->field_begin() ; fit != cv->field_end() ; fit++ ) { diff --git a/trick_source/codegen/Interface_Code_Gen/TranslationUnitVisitor.cpp b/trick_source/codegen/Interface_Code_Gen/TranslationUnitVisitor.cpp index 13352eac..0d46f2fe 100644 --- a/trick_source/codegen/Interface_Code_Gen/TranslationUnitVisitor.cpp +++ b/trick_source/codegen/Interface_Code_Gen/TranslationUnitVisitor.cpp @@ -46,29 +46,33 @@ bool TranslationUnitVisitor::TraverseDecl(clang::Decl *d) { In this case the CXXRecordDecl file name will not match the current file name, and is in fact empty */ clang::RecordDecl * rd = crd->getDefinition() ; - if ( rd != NULL and ! getFileName(ci , crd->getRBraceLoc(), hsd).empty() ) { - //crd->dump() ; std::cout << std::endl ; - if ( isInUserCode(ci , crd->getRBraceLoc(), hsd) ) { - CXXRecordVisitor cvis(ci , cs, hsd , pa, true) ; + if ( rd != NULL ) { + std::string rd_file = getFileName(ci , rd->getSourceRange().getEnd(), hsd) ; + std::string crd_file = getFileName(ci , crd->getSourceRange().getEnd(), hsd) ; + if (!crd_file.empty() and !crd_file.compare(rd_file)) { + //crd->dump() ; std::cout << std::endl ; + if ( isInUserCode(ci , crd->getSourceRange().getEnd(), hsd) ) { + CXXRecordVisitor cvis(ci , cs, hsd , pa, true) ; - cvis.TraverseCXXRecordDecl(static_cast(d)) ; - pa.printClass(cvis.get_class_data()) ; + cvis.TraverseCXXRecordDecl(static_cast(d)) ; + pa.printClass(cvis.get_class_data()) ; - /* Check to see if the struct/class is forward declared in the same file. - If it is, then remove the notation that it is forward declared. This - is to allow C structs to be forward declared and typedeffed and io_src - code will be generated for both the original structure name and typedeffed - name. + /* Check to see if the struct/class is forward declared in the same file. + If it is, then remove the notation that it is forward declared. This + is to allow C structs to be forward declared and typedeffed and io_src + code will be generated for both the original structure name and typedeffed + name. - struct Astruct ; - typedef struct Astruct {} Bstruct ; - */ - std::set< std::string >::iterator it ; - std::string file_name = getFileName(ci , d->getLocEnd(), hsd) ; - std::string source_type = cvis.get_class_data()->getName() ; - it = fwd_declared_classes[file_name].find(source_type) ; - if ( it != fwd_declared_classes[file_name].end() ) { - fwd_declared_classes[file_name].erase(it) ; + struct Astruct ; + typedef struct Astruct {} Bstruct ; + */ + std::set< std::string >::iterator it ; + std::string file_name = getFileName(ci , d->getLocEnd(), hsd) ; + std::string source_type = cvis.get_class_data()->getName() ; + it = fwd_declared_classes[file_name].find(source_type) ; + if ( it != fwd_declared_classes[file_name].end() ) { + fwd_declared_classes[file_name].erase(it) ; + } } } } else { @@ -81,7 +85,7 @@ bool TranslationUnitVisitor::TraverseDecl(clang::Decl *d) { break ; case clang::Decl::Enum : { clang::EnumDecl * ed = static_cast(d) ; - if ( isInUserCode(ci , ed->getRBraceLoc(), hsd) ) { + if ( isInUserCode(ci , ed->getSourceRange().getEnd(), hsd) ) { EnumVisitor evis(ci, hsd) ; evis.TraverseDecl(ed) ; //if ( evis.get_enum_data() != NULL ) { diff --git a/trick_source/codegen/Interface_Code_Gen/main.cpp b/trick_source/codegen/Interface_Code_Gen/main.cpp index cb4aabba..49c191ae 100644 --- a/trick_source/codegen/Interface_Code_Gen/main.cpp +++ b/trick_source/codegen/Interface_Code_Gen/main.cpp @@ -25,13 +25,13 @@ #include "PrintAttributesFactory.hh" #include "Utilities.hh" -// Command line arguments. These work better as globals, as suggested in llvm/CommandLine documentation. +/* Command line arguments. These work better as globals, as suggested in llvm/CommandLine documentation */ llvm::cl::list include_dirs("I", llvm::cl::Prefix, llvm::cl::desc("Include directory"), llvm::cl::value_desc("directory")); llvm::cl::list defines("D", llvm::cl::Prefix, llvm::cl::desc("Defines"), llvm::cl::value_desc("define")); llvm::cl::opt units_truth_is_scary("units-truth-is-scary", llvm::cl::desc("Don't print units conversion messages")); llvm::cl::opt sim_services_flag("s", llvm::cl::desc("Gernerate io_src for Trick core headers")); llvm::cl::opt force("f", llvm::cl::desc("Force all io_src files to be generated")); -llvm::cl::opt attr_version("v", llvm::cl::desc("Select version of attributes to produce. 10 and 13 are valid"), llvm::cl::init(10)); +llvm::cl::opt attr_version("v", llvm::cl::desc("Select version of attributes to produce. 10 and 13 are valid"), llvm::cl::init(10)); llvm::cl::opt debug_level("d", llvm::cl::desc("Set debug level"), llvm::cl::init(0), llvm::cl::ZeroOrMore); llvm::cl::opt create_map("m", llvm::cl::desc("Create map files"), llvm::cl::init(false)); llvm::cl::opt output_dir("o", llvm::cl::desc("Output directory")); @@ -40,8 +40,9 @@ llvm::cl::alias force_alias("force" , llvm::cl::desc("Alias for -f") , llvm::cl: llvm::cl::list input_file_names(llvm::cl::Positional, llvm::cl::desc(""), llvm::cl::ZeroOrMore); llvm::cl::list sink(llvm::cl::Sink, llvm::cl::ZeroOrMore); llvm::cl::list pre_compiled_headers("include", llvm::cl::Prefix, llvm::cl::desc("pre-compiled headers"), llvm::cl::value_desc("pre_compiled_headers")); -llvm::cl::opt global_compat15("c", llvm::cl::desc("Print the offsetof calculations in attributes")); -llvm::cl::alias compat15_alias("compat15", llvm::cl::desc("Alias for -c"), llvm::cl::aliasopt(global_compat15)); + +llvm::cl::opt global_compat15("c", llvm::cl::desc("Print the offsetof calculations in attributes")) ; +llvm::cl::alias compat15_alias ("compat15" , llvm::cl::desc("Alias for -c") , llvm::cl::aliasopt(global_compat15)) ; /** Most of the main program is pieced together from examples on the web. We are doing the following: @@ -72,61 +73,72 @@ int main(int argc, char * argv[]) { std::cerr << "No header file specified" << std::endl; return 1; } + clang::CompilerInstance ci ; +#if (LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR < 9) + clang::CompilerInvocation::setLangDefaults(ci.getLangOpts() , clang::IK_CXX) ; +#endif - clang::CompilerInstance compilerInstance; - compilerInstance.createDiagnostics(); - compilerInstance.getDiagnosticOpts().ShowColors = 1; - compilerInstance.getDiagnostics().setIgnoreAllWarnings(true); - - // Set all of the defaults to c++ - clang::CompilerInvocation::setLangDefaults(compilerInstance.getLangOpts(), clang::IK_CXX); - compilerInstance.getLangOpts().CXXExceptions = true; - + ci.createDiagnostics(); + ci.getDiagnosticOpts().ShowColors = 1 ; + ci.getDiagnostics().setIgnoreAllWarnings(true) ; + ci.getLangOpts().CXXExceptions = true ; // Activate C++11 parsing - compilerInstance.getLangOpts().CPlusPlus11 = true; + ci.getLangOpts().Bool = true ; + ci.getLangOpts().WChar = true ; + ci.getLangOpts().CPlusPlus = true ; + ci.getLangOpts().CPlusPlus11 = true ; + ci.getLangOpts().CXXOperatorNames = true ; + + // Create all of the necessary managers. + ci.createFileManager(); + ci.createSourceManager(ci.getFileManager()); + + // Tell the preprocessor to use its default predefines + clang::PreprocessorOptions & ppo = ci.getPreprocessorOpts() ; + ppo.UsePredefines = true; // Set the default target architecture #if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 5)) - clang::TargetOptions targetOptions; - targetOptions.Triple = llvm::sys::getDefaultTargetTriple(); - compilerInstance.setTarget(clang::TargetInfo::CreateTargetInfo(compilerInstance.getDiagnostics(), std::make_shared(targetOptions))); + clang::TargetOptions to; + to.Triple = llvm::sys::getDefaultTargetTriple(); + std::shared_ptr shared_to = std::make_shared(to) ; + clang::TargetInfo *pti = clang::TargetInfo::CreateTargetInfo(ci.getDiagnostics(), shared_to); + ci.setTarget(pti); + ci.createPreprocessor(clang::TU_Complete); #else - clang::TargetOptions* targetOptions = new clang::TargetOptions(); - targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); - compilerInstance.setTarget(clang::TargetInfo::CreateTargetInfo(compilerInstance.getDiagnostics(), targetOptions)); + clang::TargetOptions * to = new clang::TargetOptions() ; + to->Triple = llvm::sys::getDefaultTargetTriple(); + clang::TargetInfo *pti = clang::TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); + ci.setTarget(pti); + ci.createPreprocessor(); #endif - // Create all of the necessary managers - compilerInstance.createFileManager(); - compilerInstance.createSourceManager(compilerInstance.getFileManager()); - - // Create the preprocessor -#if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 5)) - compilerInstance.createPreprocessor(clang::TU_Complete); -#else - compilerInstance.createPreprocessor(); + // Set all of the defaults to c++ +#if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 9)) + llvm::Triple trip (to.Triple) ; + clang::CompilerInvocation::setLangDefaults(ci.getLangOpts(), clang::IK_CXX, trip, ppo) ; + // setting the language defaults clears the c++11 flag. + ci.getLangOpts().CPlusPlus11 = true ; #endif - clang::Preprocessor& preprocessor = compilerInstance.getPreprocessor(); + clang::Preprocessor& pp = ci.getPreprocessor(); // Add all of the include directories to the preprocessor - HeaderSearchDirs headerSearchDirs(compilerInstance.getPreprocessor().getHeaderSearchInfo(), compilerInstance.getHeaderSearchOpts(), preprocessor, sim_services_flag); - headerSearchDirs.addSearchDirs(include_dirs); + HeaderSearchDirs hsd(ci.getPreprocessor().getHeaderSearchInfo(), ci.getHeaderSearchOpts(), pp, sim_services_flag); + hsd.addSearchDirs(include_dirs); - // Tell the preprocessor to use its default predefines - compilerInstance.getPreprocessorOpts().UsePredefines = true; #if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 8)) - preprocessor.getBuiltinInfo().initializeBuiltins(preprocessor.getIdentifierTable(), preprocessor.getLangOpts()); + pp.getBuiltinInfo().initializeBuiltins(pp.getIdentifierTable(), pp.getLangOpts()); #else - preprocessor.getBuiltinInfo().InitializeBuiltins(preprocessor.getIdentifierTable(), preprocessor.getLangOpts()); + pp.getBuiltinInfo().InitializeBuiltins(pp.getIdentifierTable(), pp.getLangOpts()); #endif // Add all of the #define from the command line to the default predefines - headerSearchDirs.addDefines(defines); + hsd.addDefines(defines); // Add our comment saver as a comment handler in the preprocessor - CommentSaver commentSaver(compilerInstance, headerSearchDirs); - preprocessor.addCommentHandler(&commentSaver); + CommentSaver cs(ci, hsd); + pp.addCommentHandler(&cs); - PrintAttributes printAttributes(attr_version, headerSearchDirs, commentSaver, compilerInstance, force, sim_services_flag, output_dir); + PrintAttributes printAttributes(attr_version, hsd, cs, ci, force, sim_services_flag, output_dir); // Create new class and enum map files if (create_map) { @@ -134,14 +146,14 @@ int main(int argc, char * argv[]) { } // Tell the compiler to use our ICGASTconsumer - ICGASTConsumer* astConsumer = new ICGASTConsumer(compilerInstance, headerSearchDirs, commentSaver, printAttributes); + ICGASTConsumer* astConsumer = new ICGASTConsumer(ci, hsd, cs, printAttributes); #if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 6)) - compilerInstance.setASTConsumer(std::move(std::unique_ptr(astConsumer))); + ci.setASTConsumer(std::move(std::unique_ptr(astConsumer))); #else - compilerInstance.setASTConsumer(astConsumer); + ci.setASTConsumer(astConsumer); #endif - compilerInstance.createASTContext(); - compilerInstance.createSema(clang::TU_Prefix, NULL); + ci.createASTContext(); + ci.createSema(clang::TU_Prefix, NULL); // Get the full path of the file to be read char buffer[input_file_names[0].size()]; @@ -158,16 +170,16 @@ int main(int argc, char * argv[]) { exit(-1); } // Open up the input file and parse it - const clang::FileEntry* fileEntry = compilerInstance.getFileManager().getFile(inputFilePath); + const clang::FileEntry* fileEntry = ci.getFileManager().getFile(inputFilePath); free(inputFilePath); #if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 5)) - compilerInstance.getSourceManager().setMainFileID(compilerInstance.getSourceManager().createFileID(fileEntry, clang::SourceLocation(), clang::SrcMgr::C_User)); + ci.getSourceManager().setMainFileID(ci.getSourceManager().createFileID(fileEntry, clang::SourceLocation(), clang::SrcMgr::C_User)); #else - compilerInstance.getSourceManager().createMainFileID(fileEntry); + ci.getSourceManager().createMainFileID(fileEntry); #endif - compilerInstance.getDiagnosticClient().BeginSourceFile(compilerInstance.getLangOpts(), &compilerInstance.getPreprocessor()); - clang::ParseAST(compilerInstance.getSema()); - compilerInstance.getDiagnosticClient().EndSourceFile(); + ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor()); + clang::ParseAST(ci.getSema()); + ci.getDiagnosticClient().EndSourceFile(); if (!sim_services_flag) { printAttributes.printIOMakefile(); diff --git a/trick_source/codegen/Interface_Code_Gen/makefile b/trick_source/codegen/Interface_Code_Gen/makefile index e278808b..ae0a7938 100644 --- a/trick_source/codegen/Interface_Code_Gen/makefile +++ b/trick_source/codegen/Interface_Code_Gen/makefile @@ -48,7 +48,8 @@ endif endif ifeq ($(TRICK_HOST_TYPE),Darwin) -CLANGLIBS += -lLLVMOption -lLLVMMCParser -lLLVMBitReader -lLLVMMC -lLLVMSupport $(shell $(LLVM_HOME)/bin/llvm-config --system-libs) +CLANGLIBS += $(shell $(LLVM_HOME)/bin/llvm-config --libs) +CLANGLIBS += $(shell $(LLVM_HOME)/bin/llvm-config --system-libs) CLANGLIBS += -lc++abi endif