├── dummy_test ├── dm_dir │ ├── log.yaml │ ├── macro_stat.yaml │ ├── demacrofied_macro_stat.yaml │ ├── header1.h │ ├── header2.h │ └── example.cpp ├── header1.h ├── demac_backup │ ├── header1.h │ ├── header2.h │ └── example.cpp ├── header2.h ├── demac_cleanup │ ├── header1.h │ ├── header2.h │ ├── demacrofied_macro_stat.yaml │ ├── log.yaml │ ├── macro_stat.yaml │ └── example.cpp ├── CMakeLists.txt ├── Defined.h ├── example.cpp ├── ConfigFile.cfg └── gMacros.dat ├── test ├── testPointerType.cpp ├── testCComment.cpp ├── testVoidFunction.cpp ├── testCPPComment.cpp ├── testAccessOp.cpp ├── testUnclosedBrace.cpp ├── testNonDemacrofiableFunctionLike.cpp ├── testArrayOp.cpp ├── testVariadic.cpp ├── testFunctionLike.cpp ├── testObjLikeStatement.cpp ├── testNestedMacroUseCase.cpp ├── testNonDemacrofiableObjectLike.cpp ├── testconstexpr.cpp ├── testMacroWithinFunction.cpp ├── inline-function.cpp ├── testStringTypeMacro.cpp ├── testOutOfOrderMacro.cpp ├── inline-algorithm.cpp ├── test2.cpp ├── testLambdaFunction.cpp ├── testStringification.cpp ├── testConditionBlock.cpp ├── testMultipleStatements.cpp ├── testConditionals.cpp ├── testPCP3Macro.cpp ├── testVariadicMacros.cpp └── example.cpp ├── INSTALL.pdf ├── SCREENCAST ├── general_utilities ├── CMakeLists.txt ├── test │ ├── test_sizeof.cpp │ ├── CMakeLists.txt │ └── testprint_typename.cpp ├── debug.cpp ├── complex_utils.hpp ├── print_typename.hpp ├── SortFunctors.h ├── map_utils.hpp ├── set_utils.hpp ├── file_type.hpp ├── vector_utils.hpp ├── algorithm.hpp ├── sizeof.hpp ├── list_utils.hpp ├── string_utils.hpp └── debug.h ├── .gitignore ├── BuildScheme.h ├── ClangInterface ├── FunctionInfo.h ├── CMakeLists.txt ├── ASTConsumer.hpp ├── TrackMacro.hpp └── TrackMacro.cpp ├── LICENCE ├── FileManagerScheme.h ├── DemacroficationScheme.h ├── ValidatorMap.h ├── MacroStat.cpp ├── MacroStat.h ├── RlCategory.cpp ├── DemacBoostWaveIncludes.h ├── UseCaseState.cpp ├── README.md ├── HeaderDependencyBuild.cpp ├── ExceptionHandler.h ├── Tuple3_t.h ├── CondParser.h ├── UseCaseState.h ├── RlParser.h ├── ConfigScheme.h ├── ReplacementList.h ├── ReplacementList.cpp ├── MacroScopeClassifier.h ├── Overseer.h ├── ConfigScheme.cpp ├── gMacros.dat ├── CMakeLists.txt ├── RlCategory.h ├── Demacrofier.h ├── FileManager.h ├── Overseer.cpp ├── Macro.h ├── FileManager.cpp ├── Parser.h ├── gConditions.h ├── DepGraph.h └── DepGraph.cpp /dummy_test/dm_dir/log.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dummy_test/dm_dir/macro_stat.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dummy_test/dm_dir/demacrofied_macro_stat.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/testPointerType.cpp: -------------------------------------------------------------------------------- 1 | #define Ptr(X) X* 2 | -------------------------------------------------------------------------------- /test/testCComment.cpp: -------------------------------------------------------------------------------- 1 | #define N 100 /*this is the magic number*/ -------------------------------------------------------------------------------- /test/testVoidFunction.cpp: -------------------------------------------------------------------------------- 1 | #define fun() FXY(1,200,3) 2 | 3 | -------------------------------------------------------------------------------- /test/testCPPComment.cpp: -------------------------------------------------------------------------------- 1 | #define N 100 //this is the magic number 2 | -------------------------------------------------------------------------------- /INSTALL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiraditya/cpp2cxx/HEAD/INSTALL.pdf -------------------------------------------------------------------------------- /test/testAccessOp.cpp: -------------------------------------------------------------------------------- 1 | #define MALLOC(s) (parser->m_mem.malloc_fcn((s))) 2 | 3 | -------------------------------------------------------------------------------- /test/testUnclosedBrace.cpp: -------------------------------------------------------------------------------- 1 | #define OPEN_BRACE { 2 | 3 | #define CLOSING_BRACE }; -------------------------------------------------------------------------------- /dummy_test/header1.h: -------------------------------------------------------------------------------- 1 | #include "header2.h" 2 | 3 | #define header11_macro 1 4 | 5 | -------------------------------------------------------------------------------- /test/testNonDemacrofiableFunctionLike.cpp: -------------------------------------------------------------------------------- 1 | #define b(i, j) b##i[(j)*2%8 + (j)/4] 2 | 3 | -------------------------------------------------------------------------------- /SCREENCAST: -------------------------------------------------------------------------------- 1 | Tool demonstration for ICSM-2012 2 | 3 | http://www.youtube.com/watch?v=J2OepRJ2fDg -------------------------------------------------------------------------------- /dummy_test/demac_backup/header1.h: -------------------------------------------------------------------------------- 1 | #include "header2.h" 2 | 3 | #define header11_macro 1 4 | 5 | -------------------------------------------------------------------------------- /test/testArrayOp.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define a(i) aPtr[10] 3 | #define c(i) cPtr[((i)*13+16) % 17] 4 | 5 | -------------------------------------------------------------------------------- /dummy_test/header2.h: -------------------------------------------------------------------------------- 1 | #define header1_macro(x,y) x = x+y 2 | #define header3_macro(x,y) x[y] 3 | 4 | -------------------------------------------------------------------------------- /general_utilities/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_library(cpp2cxx-debug SHARED 3 | debug.cpp 4 | ) 5 | -------------------------------------------------------------------------------- /dummy_test/demac_backup/header2.h: -------------------------------------------------------------------------------- 1 | #define header1_macro(x,y) x = x+y 2 | #define header3_macro(x,y) x[y] 3 | 4 | -------------------------------------------------------------------------------- /general_utilities/test/test_sizeof.cpp: -------------------------------------------------------------------------------- 1 | #include "sizeof.hpp" 2 | 3 | int main() 4 | { 5 | sizeof_datatypes(); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/testVariadic.cpp: -------------------------------------------------------------------------------- 1 | #define NEW_EXP(cls, e...) \ 2 | cls##Ptr(new cls(BlockScopePtr(), getLocation(), ##e)) 3 | 4 | -------------------------------------------------------------------------------- /test/testFunctionLike.cpp: -------------------------------------------------------------------------------- 1 | #define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y))) 2 | #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y) 3 | 4 | -------------------------------------------------------------------------------- /test/testObjLikeStatement.cpp: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | #define shift3 bit = bit << 3 4 | int i = 10; 5 | int j; 6 | 7 | int bit = 10; 8 | shift3; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /test/testNestedMacroUseCase.cpp: -------------------------------------------------------------------------------- 1 | #define X 100 2 | #define Y 200 3 | #define F(A,B) A+B 4 | 5 | int x = F(X,Y); 6 | //test fails in this case 7 | int y = F(X+Y,100); 8 | -------------------------------------------------------------------------------- /test/testNonDemacrofiableObjectLike.cpp: -------------------------------------------------------------------------------- 1 | #define __UINTMAX_TYPE__ long long unsigned int 2 | #define TYPE_CHAR (char *) 3 | #define __WCHAR_TYPE__ int 4 | #define CRYPTOPP_CHANNELS_H 5 | -------------------------------------------------------------------------------- /test/testconstexpr.cpp: -------------------------------------------------------------------------------- 1 | //#define FILENAME "HEADER_FILE" 2 | constexpr auto FILENAME = "HEADER_FILE"; 3 | 4 | int main() 5 | { 6 | int f = FILENAME; 7 | return 0; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test/testMacroWithinFunction.cpp: -------------------------------------------------------------------------------- 1 | int fun() 2 | { 3 | int i = 10; 4 | #define INSIDE_FUN(A,B,C) A+B+C+i 5 | return INSIDE_FUN(1,2,3); 6 | } 7 | 8 | 9 | int main() 10 | { 11 | int i = fun(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/inline-function.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define f(x) x + 2 3 | #define g(x) #x 4 | 5 | //ultimately we would like to achive this for f(x) 6 | template 7 | constexpr auto f(T const& x) -> decltype(x + 2) 8 | { 9 | return x + 2; 10 | } 11 | -------------------------------------------------------------------------------- /dummy_test/dm_dir/header1.h: -------------------------------------------------------------------------------- 1 | #include "header2.h" 2 | 3 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_header11_macro_header1h_3_9) 4 | constexpr auto header11_macro = 1; 5 | #else 6 | #define header11_macro 1 7 | #endif 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /general_utilities/debug.cpp: -------------------------------------------------------------------------------- 1 | // Definitions. 2 | 3 | #include "debug.h" 4 | 5 | std::ostream *dbg_stream = &std::cout; 6 | 7 | std::ostream& dbgs() 8 | { 9 | return *dbg_stream; 10 | } 11 | 12 | void set_dbg_stream(std::ostream &os) 13 | { 14 | dbg_stream = &os; 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Temporaru files 11 | *.*~ 12 | *.tmp 13 | *.swp 14 | 15 | # Architecture specific extensions/prefixes 16 | *.[568vq] 17 | [568vq].out 18 | 19 | *.exe 20 | -------------------------------------------------------------------------------- /dummy_test/demac_cleanup/header1.h: -------------------------------------------------------------------------------- 1 | #include "header2.h" 2 | 3 | 4 | /** Demacrofication for the macro header11_macro with unique identifier USE_header11_macro_header1h_3_9*/ 5 | constexpr auto header11_macro = 1; 6 | 7 | 8 | /** Demacrofication for the macro header12_macro with unique identifier USE_header12_macro_header1h_5_9*/ 9 | constexpr auto header12_macro = 2; 10 | 11 | 12 | -------------------------------------------------------------------------------- /general_utilities/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | 3 | PROJECT(test) 4 | 5 | SET(CMAKE_CXX_FLAGS "-pedantic -Wall -g -std=c++0x") 6 | SET(FOOL_DIR /home/vmplanet/Documents/examples/cplusplus/fool/trunk/) 7 | INCLUDE_DIRECTORIES("${FOOL_DIR}/general_utilities") 8 | 9 | 10 | ADD_EXECUTABLE(test 11 | #testprint_typename.cpp 12 | test_sizeof.cpp 13 | ) 14 | -------------------------------------------------------------------------------- /test/testStringTypeMacro.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define CRYPTOPP_DUMMY_DLL_MAC "MAC_51f34b8db820ae8" 4 | #define F(X,Y) X+Y 5 | //constexpr auto CRYPTOPP_DUMMY_DLL_MAC = "MAC_51f34b8db820ae8"; 6 | 7 | //error: initializer fails to determine size of ‘mac’ 8 | int main() 9 | { 10 | unsigned char mac[] = CRYPTOPP_DUMMY_DLL_MAC; 11 | int x = F(10,15); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /dummy_test/demac_cleanup/header2.h: -------------------------------------------------------------------------------- 1 | 2 | /** Demacrofication for the macro header1_macro with unique identifier USE_header1_macro_header2h_1_9*/ 3 | template 4 | void header1_macro(_T1 && x, _T2 && y) 5 | { 6 | x+y; 7 | ; 8 | } 9 | 10 | /** Demacrofication for the macro header3_macro with unique identifier USE_header3_macro_header2h_2_9*/ 11 | template 12 | auto header3_macro(_T1 x, _T2 y) -> decltype(x[y]) 13 | { 14 | return x[y]; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/testOutOfOrderMacro.cpp: -------------------------------------------------------------------------------- 1 | #define a 100 2 | #define b 200 3 | #define c 300 4 | #define THIS_FILE __FILE__ 5 | #if +a + (-b+c) 6 | #define depth1 (1 + t1) 7 | #if !defined(a) || defined(b) && defined(c) 8 | #define depth2 (1 + depth1 + a + t1) 9 | #ifdef a 10 | #endif 11 | #ifndef __DBL_MIN_EXP__ 12 | #define depth3 (1+depth2+c+__SHRT_MAX__) 13 | #endif 14 | #endif 15 | #endif 16 | #define ai (aPtr[10] + _abc) 17 | #define FXY(X,Y,Z) ((X) + (Y)) 18 | #define fun() FXY(1,200,3) 19 | 20 | #define _abc 1000 21 | #define t1 (10*256) 22 | -------------------------------------------------------------------------------- /general_utilities/test/testprint_typename.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Aditya Kumar 3 | * 4 | * This file is distributed under the MIT License. See 5 | * LICENCE.txt attached with this project or visit 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * for terms and conditions. 8 | */ 9 | 10 | #include "print_typename.hpp" 11 | 12 | #include 13 | 14 | 15 | int main() 16 | { 17 | print_type(std::cout, "name"); 18 | std::cout< 21 | void f(T& x) 22 | { 23 | x += 2; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /dummy_test/dm_dir/header2.h: -------------------------------------------------------------------------------- 1 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_header1_macro_header2h_1_9) 2 | template 3 | void header1_macro(_T1 && x, _T2 && y) 4 | { 5 | x = x+y; 6 | } 7 | #else 8 | #define header1_macro(x,y) x = x+y 9 | #endif 10 | 11 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_header3_macro_header2h_2_9) 12 | template 13 | auto header3_macro(_T1 x, _T2 y) -> decltype(x[y]) 14 | { 15 | return x[y]; 16 | } 17 | #else 18 | #define header3_macro(x,y) x[y] 19 | #endif 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dummy_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(dummy_test) 3 | # Compiler options 4 | IF(CMAKE_COMPILER_IS_GNUCXX) 5 | MESSAGE(STATUS "GCC detected - Adding compiler flags: -pedantic -O2 -std=c++0x") 6 | SET(CMAKE_CXX_FLAGS "-pedantic -g -Wall -std=c++0x -imacros Defined.h") 7 | ELSEIF(MSVC) 8 | MESSAGE(STATUS "MSVC detected - Adding compiler flags") 9 | ENDIF(CMAKE_COMPILER_IS_GNUCXX) 10 | 11 | ##############RELATED TO CLANG######################### 12 | INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) 13 | 14 | ADD_EXECUTABLE(dummy_test 15 | example.cpp 16 | ) 17 | 18 | -------------------------------------------------------------------------------- /test/test2.cpp: -------------------------------------------------------------------------------- 1 | //#include "/media/space/opt_149739_build/lib/clang/3.1/include/stddef.h" 2 | #include 3 | #include 4 | #define A 100 5 | //#define F() A+100 6 | 7 | int f1() 8 | { 9 | #define INSIDE_FUN(i) i*100 10 | size_t i = INSIDE_FUN(100); 11 | return 0; 12 | } 13 | int f2() 14 | { 15 | #define INSIDE 100*100 16 | int i = 10; 17 | return 0; 18 | } 19 | 20 | int f3() 21 | { 22 | #define WHATEVER_IN_F3() 1 23 | int i = 10; 24 | return 0; 25 | } 26 | 27 | int f4() 28 | { 29 | int i = 10; 30 | return 0; 31 | } 32 | 33 | int main() 34 | { 35 | int i = 10; 36 | return 0; 37 | } 38 | #define pi 3.14 39 | -------------------------------------------------------------------------------- /BuildScheme.h: -------------------------------------------------------------------------------- 1 | #ifndef BUILDSCHEME_H 2 | #define BUILDSCHEME_H 3 | // (c) Copyright 4 | // ALL RIGHTS RESERVED 5 | /** 6 | * @file BuildScheme.h 7 | * @brief defines how the project being demacrofied can be build 8 | * @version 1.0 9 | * @author Aditya Kumar 10 | * @note 11 | * compiles with g++-4.5 or higher, 12 | * for compiling pass -std=c++0x to the compiler 13 | */ 14 | 15 | #include 16 | 17 | struct BuildScheme { 18 | /// @var makeCommand 19 | /// @brief the command string to be invoked for compiling the package 20 | /// to be sent to the Parser class(as of now) 21 | std::string makeCommand; 22 | }; 23 | 24 | #endif // BUILDSCHEME_H 25 | -------------------------------------------------------------------------------- /general_utilities/complex_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_COMPLEX_HPP 2 | #define UTILS_COMPLEX_HPP 3 | /* 4 | * @author Aditya Kumar 5 | * 6 | * This file is distributed under the MIT License. See 7 | * LICENCE.txt attached with this project or visit 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * for terms and conditions. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | namespace general_utilities{ 17 | template 18 | std::ostream& operator<<(std::ostream& os, std::complex c) 19 | { 20 | os<<'('< 15 | #include 16 | 17 | 18 | template 19 | void print_typeref(std::ostream& os, T const& x) 20 | { 21 | os< 26 | void print_type(std::ostream& os, T x) 27 | { 28 | os< 13 | /* 14 | bool SortString(std::string const& s1,std::string const& s2){ 15 | return s1.compare(s2) < 0; 16 | } 17 | */ 18 | namespace general_utilities { 19 | struct SortString { 20 | bool operator()(std::string const& s1,std::string const& s2) const 21 | { 22 | return s1.compare(s2) < 0; 23 | } 24 | }; 25 | 26 | } 27 | #endif // SORTFUNCTORS_H 28 | -------------------------------------------------------------------------------- /dummy_test/Defined.h: -------------------------------------------------------------------------------- 1 | #define USE_fun_examplecpp_12_9 1 2 | #define USE__c_examplecpp_7_9 1 3 | #define USE_depth0_examplecpp_3_9 1 4 | #define USE_b_examplecpp_5_9 1 5 | #define USE_header12_macro_header1h_5_9 1 6 | #define USE_INSIDE_FUN_SUPER_examplecpp_18_9 1 7 | #define USE_header1_macro_header2h_1_9 1 8 | #define USE_FXY_examplecpp_11_9 1 9 | #define USE_a_examplecpp_4_9 1 10 | #define USE_LSB_examplecpp_38_9 1 11 | #define USE_TSB_examplecpp_37_9 1 12 | #define USE_SSB_examplecpp_36_9 1 13 | #define USE_MSB_examplecpp_35_9 1 14 | #define USE_header11_macro_header1h_3_9 1 15 | #define USE_proc_examplecpp_32_9 1 16 | #define USE__a_examplecpp_8_9 1 17 | #define USE_INSIDE_FUN_examplecpp_55_9 1 18 | #define USE_header3_macro_header2h_2_9 1 19 | -------------------------------------------------------------------------------- /test/testLambdaFunction.cpp: -------------------------------------------------------------------------------- 1 | int super(int i) 2 | { 3 | 4 | #define INSIDE_FUN_SUPER(X,Y) X+100 + j 5 | 6 | //variable 'j' referenced in macro INSIDE_FUN_SUPER 7 | // //the transformation has to be carefully placed after the declaration of 'int j' 8 | int j = 10; 9 | return INSIDE_FUN_SUPER(10000, 4000); 10 | } 11 | 12 | int j = 10; 13 | #define OUTSIDE_FUN_SUPER(X,Y) X+100 + j 14 | 15 | 16 | int k = OUTSIDE_FUN_SUPER(10000, 4000); 17 | 18 | 19 | 20 | /* 21 | template 22 | void f(T const& t) 23 | { 24 | int S[] = {1, 2,3, 3,4,5}; 25 | #define S0(X) S[X] 26 | #define SHIFT(X) X< 14 | #include 15 | namespace general_utilities{ 16 | template 17 | std::ostream& operator<<(std::ostream& os,const std::map& m) 18 | { 19 | for(typename std::map::const_iterator i = m.begin(); i!= m.end(); ++i){ 20 | os<first; 21 | os<<"\t"; 22 | os<second; 23 | os<<"\n"; 24 | } 25 | return os; 26 | } 27 | } 28 | #endif // UTILS_MAP_HPP 29 | -------------------------------------------------------------------------------- /ClangInterface/FunctionInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTION_INFO 2 | #define FUNCTION_INFO 3 | 4 | 5 | #include "MacroScopeClassifier.h" 6 | #include "vector_utils.hpp" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | struct ParsedDeclInfo{ 13 | std::size_t start_line; 14 | std::size_t end_line; 15 | }; 16 | 17 | struct CollectedMacroInfo{ 18 | std::size_t defined_line; 19 | std::vector invoked_lines; 20 | PPOperation op; 21 | MacroCategory m_cat; 22 | CondCategory c_cat; 23 | MacroScopeCategory s_cat; 24 | }; 25 | typedef std::string MacroNameStr; 26 | typedef std::map ASTMacroStat_t; 27 | typedef std::multiset InvocationStat_t; 28 | //typedef std::multimap InvocationStat_t; 29 | #endif // FUNCTION_INFO 30 | -------------------------------------------------------------------------------- /general_utilities/set_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_SET_HPP 2 | #define UTILS_SET_HPP 3 | /* 4 | * @author Aditya Kumar 5 | * 6 | * This file is distributed under the MIT License. See 7 | * LICENCE.txt attached with this project or visit 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * for terms and conditions. 10 | */ 11 | 12 | 13 | 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace general_utilities{ 21 | // A helper function to simplify the main part. 22 | template 23 | std::ostream& operator<<(std::ostream& os, const std::set& s) 24 | { 25 | 26 | //std::for_each(s.begin(), s.end(), [&os](const T& t){os<(os, "\n")); 28 | return os; 29 | } 30 | } 31 | #endif // PRINTSET_H 32 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | cpp2cxx is an open source software distributed under terms of the 2 | Apache2.0 licence. 3 | 4 | Copyrights remain with the original copyright holders. 5 | Use of this material is by permission and/or license. 6 | 7 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | -------------------------------------------------------------------------------- /test/testStringification.cpp: -------------------------------------------------------------------------------- 1 | /* Original Macro with stringification */ 2 | #include 3 | 4 | #define WARN_IF(EXP) \ 5 | do { if (EXP) \ 6 | fprintf (stderr, "Warning: " #EXP "\n"); } \ 7 | while (0) 8 | 9 | int main() 10 | { 11 | int x = 0; 12 | WARN_IF(x==0); 13 | int i = 1; 14 | WARN_IF(i); 15 | return 0; 16 | } 17 | 18 | /* Modified Alternative */ 19 | #include 20 | #include 21 | //just need to copy the function argument as string and 22 | //pass that as a new argument 23 | template 24 | void WARN_IF(T1 EXP, std::string str) 25 | { 26 | do { if (EXP) 27 | fprintf (stderr, std::string("Warning: " + str + "\n").c_str()); } 28 | while (0); 29 | } 30 | 31 | int main() 32 | { 33 | int x = 0; 34 | WARN_IF(x==0,"x==0"); 35 | int i = 1; 36 | WARN_IF(i,"i"); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /test/testConditionBlock.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(a) || defined(b) && defined(c) 2 | #define depth1 __LINE__ 3 | #elif CRYPTOPP_FAST_ROTATE(32) 4 | #define depth1 __FILE__ 5 | #endif 6 | 7 | /* 8 | * #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) 9 | * */ 10 | template 11 | CRYPTOPP_COMPILE_ASSERT(T1 assertion) -> decltype(CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)) 12 | { 13 | return CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__); 14 | } 15 | //---------------------------------------------------------------------------------------- 16 | template 17 | inline GetBlock & operator()(U &x) 18 | { 19 | CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T)); 20 | x = GetWord(A, B::ToEnum(), m_block); 21 | m_block += sizeof(T); 22 | return *this; 23 | } 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /general_utilities/file_type.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_FILETYPE_HPP 2 | #define UTILS_FILETYPE_HPP 3 | 4 | /* 5 | * @author Aditya Kumar 6 | * 7 | * This file is distributed under the MIT License. See 8 | * LICENCE.txt attached with this project or visit 9 | * http://www.opensource.org/licenses/mit-license.php 10 | * for terms and conditions. 11 | */ 12 | 13 | 14 | 15 | #include "string_utils.hpp" 16 | 17 | #include 18 | 19 | namespace general_utilities { 20 | bool header_file(std::string const& filename) 21 | { 22 | if(ends_with(filename, ".h") 23 | || ends_with(filename, ".hpp")) 24 | return true; 25 | return false; 26 | } 27 | 28 | bool cpp_file(std::string const& filename) 29 | { 30 | if(ends_with(filename, ".cpp") 31 | || ends_with(filename, ".cxx") 32 | || ends_with(filename, ".C")) 33 | return true; 34 | return false; 35 | 36 | } 37 | } 38 | #endif // FILETYPE_HPP 39 | -------------------------------------------------------------------------------- /test/testMultipleStatements.cpp: -------------------------------------------------------------------------------- 1 | //test multiple statements 2 | #define proc(X,Y) {\ 3 | FXY(X,Y,0);\ 4 | } 5 | 6 | #define mu(a0, a1, a2) \ 7 | { \ 8 | a1 = reverseBits(a1); \ 9 | word32 t = reverseBits(a0); \ 10 | a0 = reverseBits(a2); \ 11 | a2 = t; \ 12 | } 13 | 14 | //OUTPUT-Date: July 07, 2011 15 | //test multiple statements 16 | 17 | // /* 18 | // #define proc(X,Y) { FXY(X,Y,0); } 19 | // */ 20 | // template 21 | // void proc(T1 X, T2 Y) 22 | // { FXY(X,Y,0); } 23 | // 24 | // 25 | // /* 26 | // #define mu(a0, a1, a2) { a1 = reverseBits(a1); word32 t = reverseBits(a0); a0 = reverseBits(a2); a2 = t; } 27 | // */ 28 | // template 29 | // void mu(T1 a0, T2 a1, T3 a2) 30 | // { a1 = reverseBits(a1); word32 t = reverseBits(a0); a0 = reverseBits(a2); a2 = t; } 31 | -------------------------------------------------------------------------------- /test/testConditionals.cpp: -------------------------------------------------------------------------------- 1 | #define CRYPTOPP_X86_ASM_AVAILABLE 2 | #define depth0 0 3 | #if +a + (-b+c) 4 | #define depth1 1 5 | #if !defined(a) || defined(b) && defined(c) 6 | #define depth2 2 7 | #ifdef a 8 | #endif 9 | #ifndef __DBL_MIN_EXP__ 10 | #define depth3 3 11 | #endif 12 | #endif 13 | #endif 14 | 15 | 16 | #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) 17 | #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) 18 | #elif defined(__MWERKS__) && TARGET_CPU_PPC 19 | return (word32)__lwbrx(&value,0); 20 | #elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) 21 | return _byteswap_ulong(value); 22 | #elif CRYPTOPP_FAST_ROTATE(32) 23 | // 5 instructions with rotate instruction, 9 without 24 | return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); 25 | #else 26 | // 6 instructions with rotate instruction, 8 without 27 | value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); 28 | return rotlFixed(value, 16U); 29 | #endif 30 | 31 | #include 32 | int main() 33 | { 34 | std::cout<<"Hello World\n"; 35 | } 36 | -------------------------------------------------------------------------------- /general_utilities/vector_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_VECTOR_HPP 2 | #define UTILS_VECTOR_HPP 3 | /* 4 | * @author Aditya Kumar 5 | * 6 | * This file is distributed under the MIT License. See 7 | * LICENCE.txt attached with this project or visit 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * for terms and conditions. 10 | */ 11 | 12 | 13 | #include 14 | #include 15 | namespace general_utilities{ 16 | // A helper function to simplify the main part. 17 | template 18 | std::ostream& operator<<(std::ostream& os,const std::vector& v) 19 | { 20 | for(typename std::vector::const_iterator i = v.begin(); i!= v.end(); ++i){ 21 | os<<*i; 22 | os<<"\n"; 23 | } 24 | return os; 25 | } 26 | 27 | #ifdef USE_ITERATORS 28 | #include 29 | 30 | template 31 | std::ostream& operator<<(std::ostream& os, const std::vector& v) 32 | { 33 | std::copy(v.begin(), v.end(), std::ostream_iterator(os, "\n")); 34 | return os; 35 | } 36 | 37 | #endif 38 | 39 | } 40 | #endif // UTILS_VECTOR_HPP 41 | -------------------------------------------------------------------------------- /test/testPCP3Macro.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | //this macro has been taken from the pcp3 paper by Ernst Et al. 3 | /* 4 | #define FOO 100 5 | #define TA3(x,y) y + x 6 | #define TA4(x,y) x + y 7 | #define PA2(x) x + FOO 8 | #define PA3(x) x + 4 9 | int main() 10 | { 11 | int a = 10; 12 | int b = 20; 13 | int c = TA4(TA3(PA2(a),PA3(b)),FOO); 14 | std::cout< 19 | constexpr auto FOO = 100; 20 | 21 | template 22 | inline auto TA3(_T1 x, _T2 y) -> decltype(y + x) 23 | { 24 | return y + x; 25 | } 26 | 27 | template 28 | inline auto TA4(_T1 x, _T2 y) -> decltype(x + y) 29 | { 30 | return x + y; 31 | } 32 | 33 | template 34 | inline auto PA2(_T1 x) -> decltype(x + FOO) 35 | { 36 | return x + FOO; 37 | } 38 | 39 | template 40 | inline auto PA3(_T1 x) -> decltype(x + 4) 41 | { 42 | return x + 4; 43 | } 44 | 45 | int main() 46 | { 47 | int a = 10; 48 | int b = 20; 49 | int c = TA4(TA3(PA2(a),PA3(b)),FOO); 50 | std::cout< 18 | size_t abs(const T1 & t1) const 19 | { 20 | return t1 <0 ? -t1 : t1; 21 | } 22 | 23 | //returns the maximum of two 24 | //if both have the same value then it returns the first one 25 | template 26 | const T& max(const T& t1, const T& t2) const 27 | { 28 | return t1 < t2 ? t2 : t1; 29 | } 30 | 31 | //returns the minimum of two 32 | //if both have the same value then it returns the first one 33 | template 34 | const T& min(const T& t1, const T& t2) const 35 | { 36 | return t1 > t2 ? t2 : t1; 37 | } 38 | 39 | } //namespace general_utilities 40 | 41 | 42 | 43 | #endif //UTILS_ALGORITHM_HPP 44 | -------------------------------------------------------------------------------- /FileManagerScheme.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEMANAGERSCHEME_H 2 | #define FILEMANAGERSCHEME_H 3 | 4 | /** 5 | * @file FileManagerScheme.h 6 | * @brief defines the configuration for the FileManager 7 | * @version 1.0 8 | * @author Aditya Kumar 9 | * @note 10 | * compiles with g++-4.5 or higher, 11 | * for compiling pass -std=c++0x to the compiler 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /** 19 | * @struct FileManagerScheme 20 | * @brief defines the configuration for the FileManager 21 | */ 22 | struct FileManagerScheme { 23 | std::ostream* pLogFile; 24 | std::ostream* pDemacrofiedMacroStatFile; 25 | std::ostream* pMacroStatFile; 26 | std::vector inputFiles; 27 | std::vector outputFiles; 28 | std::vector searchPaths; 29 | std::string inputDirectory; 30 | std::string outputDirectory; 31 | std::string backupDirectory; 32 | std::string cleanup_directory; 33 | std::string validator_file; 34 | }; 35 | 36 | #endif // FILEMANAGERSCHEME_H 37 | -------------------------------------------------------------------------------- /dummy_test/example.cpp: -------------------------------------------------------------------------------- 1 | #include "header1.h" 2 | 3 | #define A 100 4 | 5 | #define _c(i) i 6 | #define _a(i) i*i 7 | 8 | #define CRYPTOPP_X86_ASM_AVAILABLE 9 | #define FXY(X,Y,Z) ((X) + (Y)) 10 | #define fun() FXY(1,200,3) 11 | 12 | int i = fun(); 13 | int super(int i) 14 | { 15 | 16 | #define INSIDE_FUN_SUPER(X,Y) X+100 + j 17 | 18 | //variable 'j' referenced in macro INSIDE_FUN_SUPER 19 | //the transformation has to be carefully placed after the declaration of 'int j' 20 | int j = 10; 21 | 22 | return INSIDE_FUN_SUPER(10000, 4000); 23 | } 24 | int l = FXY((i+i),super(10),100); 25 | 26 | 27 | 28 | #define proc(X,Y) {\ 29 | X = FXY(X,Y,0);\ 30 | } 31 | #define MSB(x) (((x) >> 24) & 0xffU) /* most significant byte */ 32 | 33 | #include 34 | 35 | int main() 36 | { 37 | int a1 = A; 38 | std::cout<<"\na1 = "<> 24) & 0xffU) /* most significant byte */ 32 | 33 | #include 34 | 35 | int main() 36 | { 37 | int a1 = A; 38 | std::cout<<"\na1 = "< 18 | #include 19 | 20 | /** 21 | * @struct DemacroficationScheme 22 | * @brief contains the details which will be used by the Parser class 23 | * and other subclasses for configuration 24 | */ 25 | struct DemacroficationScheme { 26 | ///@var enableWarningFlag 27 | ///@details whether to enable the warning or not 28 | ///to be used instead of the ENABLE_WARNING macro 29 | ///if this flag is set then check for the struct warningLogFile 30 | bool enableWarningFlag; 31 | bool multipleDefinitions; 32 | bool performCleanup; 33 | 34 | std::set macrosPreventingDemacrofication; 35 | 36 | std::string demacroficationGranularity; 37 | std::string globalMacrosRaw; 38 | std::string globalMacrosFormatted; 39 | ValidatorMap validatorMap; 40 | }; 41 | 42 | #endif // DEMACROFICATIONSCHEME_H 43 | -------------------------------------------------------------------------------- /ValidatorMap.h: -------------------------------------------------------------------------------- 1 | #ifndef VALIDATORMAP_H 2 | #define VALIDATORMAP_H 3 | 4 | #include "ExceptionHandler.h" 5 | #include "set_utils.hpp" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | typedef std::set ValidMacros_t; 13 | 14 | class ValidatorMap{ 15 | 16 | public: 17 | void InitValidatorMap(std::string const& v_file) 18 | { 19 | validator_file = v_file; 20 | std::ifstream p_file(validator_file); 21 | if(!p_file.is_open()) 22 | throw ExceptionHandler("could not open the validator file"); 23 | std::string dummy; 24 | int val; 25 | while(p_file.good()){ 26 | std::string macro_id; 27 | //#define macro_switch 1 28 | p_file>>dummy; //#define 29 | p_file>>macro_id; //macro_id 30 | p_file>>val; //replacement text 31 | validated_macros.insert(macro_id); 32 | } 33 | using namespace general_utilities; 34 | #ifdef DEBUG_VALIDATOR 35 | std::cout<<"\nMacro switches are:\n"; 36 | std::cout< 26 | #include 27 | static unsigned int macro_count = 0; 28 | std::ostream& operator<<(std::ostream& os,MacroStat const& m_stat) 29 | { 30 | os<< "- macro" 31 | << std::setw(sizeof(double)) 32 | << std::setfill('0') 33 | << macro_count++<<":\n" 34 | <<" - m_id : "< 28 | #include 29 | enum class MacroCategory; 30 | 31 | /// use a smart pointer for resource management 32 | struct MacroStat{ 33 | MacroCategory m_cat; 34 | RlDCat rl_dcat; 35 | RlCCat rl_ccat; 36 | std::string id_string; 37 | std::string rep_list; 38 | }; 39 | 40 | std::ostream& operator<<(std::ostream& os,MacroStat const& m_stat); 41 | std::ostream& operator<<(std::ostream& os, const std::vector& v); 42 | #endif // MACROSTAT_H 43 | -------------------------------------------------------------------------------- /general_utilities/sizeof.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIZEOF_DATATYPES_HPP 2 | #define SIZEOF_DATATYPES_HPP 3 | /* 4 | * @author Aditya Kumar 5 | * 6 | * This file is distributed under the MIT License. See 7 | * LICENCE.txt attached with this project or visit 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * for terms and conditions. 10 | */ 11 | 12 | #include 13 | 14 | 15 | class NoElem{ 16 | 17 | }; 18 | 19 | class OneFunc{ 20 | int f(){ return 0; } 21 | }; 22 | 23 | class OneVirtFunc{ 24 | virtual int f(){ return 0; } 25 | }; 26 | 27 | 28 | int sizeof_datatypes() 29 | { 30 | std::cout << "Size of short is " << sizeof(short) << "\n"; 31 | std::cout << "Size of int is " << sizeof(int) << "\n"; 32 | std::cout << "Size of long is " << sizeof(long) << "\n"; 33 | std::cout << "Size of float is " << sizeof(float) << "\n"; 34 | std::cout << "Size of double is " << sizeof(double) << "\n"; 35 | std::cout << "Size of long double is " << sizeof(long double) << "\n"; 36 | std::cout << "Size of char is " << sizeof(char) << "\n"; 37 | std::cout << "Size of bool is " << sizeof(bool) << "\n"; 38 | std::cout << "Size of class with no element is " << sizeof(NoElem) << "\n"; 39 | std::cout << "Size of class with one function is " << sizeof(OneFunc) << "\n"; 40 | std::cout << "Size of class with one virtual function is " << sizeof(OneVirtFunc) << "\n"; 41 | 42 | return 0; 43 | } 44 | 45 | #endif // SIZEOF_DATATYPES_HPP 46 | -------------------------------------------------------------------------------- /RlCategory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #include "RlCategory.h" 24 | //TODO: have to change the nomenclature at every place 25 | // 26 | std::ostream& operator<<(std::ostream& os,RlDCat const& cat) 27 | { 28 | switch(cat){ 29 | case RlDCat::dependent: 30 | os<<"dependent"; 31 | break; 32 | case RlDCat::independent: 33 | os<<"closed"; //previously "independent"; 34 | break; 35 | } 36 | return os; 37 | } 38 | 39 | std::ostream& operator<<(std::ostream& os,RlCCat const& cat) 40 | { 41 | switch(cat){ 42 | case RlCCat::closed: 43 | os<<"complete"; //previously "closed"; 44 | break; 45 | case RlCCat::open: 46 | os<<"partial"; //previously "open"; 47 | break; 48 | } 49 | return os; 50 | } 51 | -------------------------------------------------------------------------------- /dummy_test/demac_cleanup/log.yaml: -------------------------------------------------------------------------------- 1 | ./example.cpp: 2 | - log: parsing replacement list: '0' of macro: depth0 3 | - log: parsing replacement list: '100' of macro: a 4 | - log: parsing replacement list: '200' of macro: b 5 | - log: parsing replacement list: 'i' of macro: _c 6 | - log: parsing replacement list: 'i*i' of macro: _a 7 | - log: parsing replacement list: '' of macro: CRYPTOPP_X86_ASM_AVAILABLE 8 | - log: parsing replacement list: '((X) + (Y))' of macro: FXY 9 | - log: parsing replacement list: 'FXY(1,200,3)' of macro: fun 10 | - log: parsing replacement list: 'X+100 + j' of macro: INSIDE_FUN_SUPER 11 | - log: parsing replacement list: '{ FXY(X,Y,0); }' of macro: proc 12 | - log: parsing replacement list: '(((x) >> 24) & 0xffU) /* most significant byte */' of macro: MSB 13 | - log: parsing replacement list: '(((x) >> 16) & 0xffU) /* second in significance */' of macro: SSB 14 | - log: parsing replacement list: '(((x) >> 8) & 0xffU) /* third in significance */' of macro: TSB 15 | - log: parsing replacement list: '(((x) ) & 0xffU) /* least significant byte */' of macro: LSB 16 | - log: parsing replacement list: 'X+100' of macro: INSIDE_FUN 17 | - log: checking the dependency order of macro depth0 18 | ./header1.h: 19 | - log: parsing replacement list: '1' of macro: header11_macro 20 | - log: parsing replacement list: '2' of macro: header12_macro 21 | - log: checking the dependency order of macro header11_macro 22 | ./header2.h: 23 | - log: parsing replacement list: 'x+y;' of macro: header1_macro 24 | - log: parsing replacement list: 'x[y]' of macro: header3_macro 25 | - log: checking the dependency order of macro header1_macro(x,y) 26 | -------------------------------------------------------------------------------- /DemacBoostWaveIncludes.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMACBOOSTWAVEINCLUDES_H 2 | #define DEMACBOOSTWAVEINCLUDES_H 3 | 4 | /** 5 | * @file DemacBoostWaveIncludes.h 6 | * @brief contains the typedefs included in the files using the boost::wave 7 | * library. Also contains the functor to sort the tokens 8 | * useful in case where tokens are used as index types in a map 9 | * @version 1.0 10 | * @author Aditya Kumar 11 | * @note 12 | * compiles with g++-4.5 or higher, 13 | * for compiling pass -std=c++0x to the compiler 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | typedef boost::wave::cpplexer::lex_token<> token_type; 24 | typedef boost::wave::cpplexer::lex_iterator token_iterator; 25 | typedef token_type::position_type position_type; 26 | 27 | /** 28 | * @struct TokenOrder 29 | * @brief To sort tokens based on their lexical order 30 | */ 31 | struct TokenOrder { 32 | bool operator()(const token_type t1, const token_type t2) const 33 | { 34 | return t1.get_value() < t2.get_value(); 35 | } 36 | }; 37 | 38 | template 39 | std::ostream& operator<<(std::ostream& os,std::mapconst& m) 40 | { 41 | std::for_each(m.begin(),m.end(), 42 | [&os](std::pair const& elem) { 43 | os<get_value(); 46 | } 47 | 48 | if(numParens == 0){ 49 | PutArgEnd(tok_iter); 50 | MakeEntry(pp); 51 | SetUseCaseString(pp); 52 | done = true; 53 | } 54 | 55 | return numParens; 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cpp2cxx 2 | ------------------------------------------------------------------------------------------------------------- 3 | 4 | Introduction: 5 | 6 | A framework of C Preprocessor analysis and source code rejuvenation tools that perform the task of demacrofication (source to source translation of C++ programs by replacing C Preprocessor macros with equivalent C++11 declarations). 7 | It is a set of three tools (i.e., cpp2cxx-suggest, cpp2cxx-validate, and cpp2cxx-finalize). 8 | 9 | ------------------------------------------------------------------------------------------------------------- 10 | 11 | User guide and installation details: 12 | INSTALL.pdf 13 | 14 | https://github.com/hiraditya/cpp2cxx/blob/master/INSTALL.pdf 15 | 16 | 17 | ------------------------------------------------------------------------------------------------------------- 18 | 19 | Builds with 20 | **llvm/clang-3.8** 21 | 22 | ------------------------------------------------------------------------------------------------------------- 23 | 24 | Paper explaining the concepts of demacrofication: 25 | 26 | A. Kumar, A. Sutton, and B. Stroustrup, "Rejuvenating C++ Programs through Demacrofication", in Software Maintenance, 2012. ICSM 2012. IEEE Conference on. IEEE, 2012, p. to appear 27 | 28 | ------------------------------------------------------------------------------------------------------------- 29 | 30 | Video screencast demonstrating the working of the framework: 31 | 32 | http://www.youtube.com/watch?v=J2OepRJ2fDg 33 | 34 | ------------------------------------------------------------------------------------------------------------- 35 | 36 | We have demacrofied version of the following three libraries (available upon request): 37 | 38 | 1. facebook-hiphop-php 39 | 40 | 2. scintilla-3.0.4 41 | 42 | 3. p7zip-9.20.1 43 | -------------------------------------------------------------------------------- /general_utilities/list_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_LIST_HPP 2 | #define UTILS_LIST_HPP 3 | /* 4 | * @author Aditya Kumar 5 | * 6 | * This file is distributed under the MIT License. See 7 | * LICENCE.txt attached with this project or visit 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * for terms and conditions. 10 | */ 11 | 12 | namespace general_utilities{ 13 | 14 | template 15 | // equality_comparable 16 | // @brief deletes a node from the list 17 | Node_type* delete_node(Node_type* head, Node_type* victim) 18 | { 19 | Node_type* n = head; 20 | if(*n == *victim){ //equality comparable 21 | head = head->next; 22 | delete n; 23 | return head; 24 | } 25 | while(n->next){ 26 | if(*(n.next) == *victim){ 27 | Node_type* temp = n.next; 28 | n.next = n.next.next; 29 | delete temp; 30 | break; 31 | } 32 | } 33 | return head; 34 | } 35 | 36 | template 37 | // equality_comparable 38 | // @brief finds the n-th last element of the list in 39 | // in linear time complexity 40 | Node_type* nth_to_last(Node_type* head, unsigned int n) 41 | { 42 | if(!head) 43 | return 0; 44 | Node_type *p1,*p2; 45 | p1 = p2 = head; 46 | for(unsigned int i = 0; i < n-1; ++i){ 47 | if(!p2) 48 | return 0;//size of the list is < n 49 | else 50 | p2 = p2->next; 51 | } 52 | while(p2->next){ 53 | p1 = p1->next; 54 | p2 = p2->next; 55 | } 56 | return p1; 57 | } 58 | 59 | #include 60 | // @brief Prints the elements of the list, one element per line 61 | template 62 | std::ostream& operator<<(std::ostream& os, const std::list& v) 63 | { 64 | std::copy(v.begin(), v.end(), std::ostream_iterator(os, "\n")); 65 | return os; 66 | } 67 | 68 | #endif 69 | } 70 | #endif // UTILS_LIST_HPP 71 | 72 | -------------------------------------------------------------------------------- /HeaderDependencyBuild.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | std::ostream& operator<<(std::ostream& os,std::set const& l) 10 | { 11 | std::for_each(l.begin(),l.end(), 12 | [&os](T t){ 13 | os<<" - "< files_list 21 | // it outputs in following format 22 | // file_name: #include "header.h" or 23 | // and this program takes format 24 | // file_name header.h 25 | // so all it requires is: 26 | // a. removal of #include, 27 | // b. removal of quotes/ angle brackets 28 | // c. removal of the colon(:) sign 29 | int main() 30 | { 31 | //the files is represented as follows 32 | //file1 file2 33 | //that means file1 includes file2 as header 34 | const char* file_name = "files_list"; 35 | ifstream fp(file_name); 36 | if(!fp.is_open()) 37 | return -1; 38 | 39 | pair file_include_pair; 40 | map > dep_list; 41 | while(fp.good()){ 42 | fp >> file_include_pair.first; 43 | fp >> file_include_pair.second; 44 | //what we want is an index on header file 45 | //so that we know how many files include this particular header-file 46 | dep_list[file_include_pair.second].insert(file_include_pair.first); 47 | } 48 | 49 | //print the list 50 | //make sure the dm_dir is already there 51 | ofstream ofp("dm_dir/include_dependency.yaml"); 52 | if(!ofp.is_open()) 53 | return -1; 54 | map >::iterator dep_list_iter; 55 | for_each(dep_list.begin(), dep_list.end(), 56 | [&ofp](pair > p){ 57 | std::cout<<"\nPrinting "< 18 | #include 19 | /** 20 | * @class ExceptionHandler 21 | * To handle exceptions 22 | * @TODO: Change the name to exception 23 | * Handle exception thrown as ExceptionHandler(const PPMacro* mac, std::string msg) 24 | */ 25 | class ExceptionHandler { 26 | public: 27 | 28 | ExceptionHandler() : message("Unknown Exception") 29 | {} 30 | 31 | ExceptionHandler(int i) : error_code(i) 32 | {} 33 | 34 | ExceptionHandler(std::string msg) : message(msg) 35 | {} 36 | 37 | ExceptionHandler(token_type const& tok, std::string msg) 38 | { 39 | std::stringstream err_msg; 40 | err_msg << " - exception note: "; 41 | err_msg //<get_identifier(); 53 | err_msg < 14 | namespace general_utilities{ 15 | // instead of all these function i can use my mapper 16 | // and then apply the predicate to each character in the string 17 | 18 | /// \brief removes the character pointed to by c_ptr 19 | /// and returns a new string. 20 | inline std::string remove_char(std::string const& str, const char* c_ptr) 21 | { 22 | std::string::size_type i = 0; 23 | std::string s_new(str,0,str.size()-1); 24 | for( ; i < str.size(); ++i) 25 | if(*c_ptr == str[i]) 26 | break; 27 | for(; i < str.size()-1; ++i) 28 | s_new[i] = str[i+i]; 29 | return s_new; 30 | } 31 | 32 | /// @brief removes all occurences of character c in string str 33 | inline std::string remove_char(std::string const& str, char c) 34 | { 35 | std::string::size_type i = 0; 36 | std::string s_new; 37 | for(;i 5 | 6 | template 7 | class Tuple3_t { 8 | public: 9 | T1 first; 10 | T2 second; 11 | T3 third; 12 | Tuple3_t(T1 const& f,T2 const& s,T3 const& t) 13 | :first(f),second(s),third(t) 14 | { } 15 | void SetFirst(T1 const& f) { first = f; } 16 | void SetSecond(T2 const& s) { second = s; } 17 | void SetThird(T3 const& t) { third = t; } 18 | T1& GetFirst() { return first; } 19 | T2& GetSecond(){ return second; } 20 | T3& GetThird() { return third; } 21 | }; 22 | 23 | //3 tuple to be printed in yaml format 24 | template 25 | std::ostream& operator<<(std::ostream& os, Tuple3_t const& t) 26 | { 27 | os<<" -id: "< 34 | class Tuple4_t { 35 | public: 36 | T1 first; 37 | T2 second; 38 | T3 third; 39 | T4 fourth; 40 | Tuple4_t(T1 const& f,T2 const& s,T3 const& t,T4 const& ft) 41 | :first(f),second(s),third(t),fourth(ft) 42 | { } 43 | void SetFirst(T1 const& f) { first = f; } 44 | void SetSecond(T2 const& s) { second = s; } 45 | void SetThird(T3 const& t) { third = t; } 46 | void SetThird(T4 const& ft) { fourth = ft; } 47 | T1& GetFirst() { return first; } 48 | T2& GetSecond(){ return second; } 49 | T3& GetThird() { return third; } 50 | T4& GetFourth(){ return fourth; } 51 | }; 52 | 53 | //4 tuple to be printed in yaml format 54 | template 55 | std::ostream& operator<<(std::ostream& os, Tuple4_t const& t) 56 | { 57 | os< 35 | 36 | /****************************************************************************** 37 | * 38 | *****************************************************************************/ 39 | class MyASTConsumer : public clang::ASTConsumer 40 | { 41 | 42 | public: 43 | MyASTConsumer() : clang::ASTConsumer() 44 | { 45 | } 46 | 47 | ~MyASTConsumer() 48 | { 49 | } 50 | 51 | virtual bool HandleTopLevelDecl(clang::DeclGroupRef d); 52 | int InitializeCI(clang::CompilerInstance& ci, 53 | std::vector const& search_paths); 54 | 55 | void DumpContent(std::string const& file_name); 56 | void PrintSourceLocation(clang::FunctionDecl* fd); 57 | void PrintSourceLocation(clang::SourceManager& sm, clang::SourceLocation loc); 58 | void PrintStats(); 59 | void VerifyMacroScope(bool use_fast); 60 | ASTMacroStat_t GetMacroStat(); 61 | InvocationStat_t* GetInvocationStat(){ return track_macro->GetInvocationStat(); } 62 | private: 63 | clang::CompilerInstance *pci; 64 | 65 | //MyASTConsumer *astConsumer; 66 | /// \brief clang::TrackMacro is defined by me 67 | /// the delete operator should not be called on track_macro 68 | /// because it is added to a reference counted Preprocessor class 69 | clang::TrackMacro *track_macro; 70 | 71 | std::string current_file; 72 | 73 | /// \brief clang::Info is defined by me 74 | std::map FunctionInfo; 75 | }; 76 | 77 | std::ostream& operator<<(std::ostream& os,const ParsedDeclInfo& inf); 78 | -------------------------------------------------------------------------------- /CondParser.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef CONDPARSER_H 24 | #define CONDPARSER_H 25 | 26 | // (c) Copyright 27 | // ALL RIGHTS RESERVED 28 | /** 29 | * @file CondParser.h 30 | * @brief parses the conditional block of the macro, and builds the tree 31 | * with nodes as conditional blocks and macros as elements 32 | * @version 1.0 33 | * @author Aditya Kumar 34 | * @note 35 | * compiles with g++-4.5 or higher, 36 | * for compiling pass -std=c++0x to the compiler 37 | */ 38 | 39 | #include "DepGraph.h" 40 | #include "DemacBoostWaveIncludes.h" 41 | 42 | #include 43 | #include 44 | 45 | typedef std::map MacroList_t; 48 | 49 | /** 50 | * @class CondParser 51 | * To parse the tokens of the preprocessing conditional statements 52 | */ 53 | class CondParser { 54 | 55 | public: 56 | CondParser(std::string file_global_macros); 57 | void Parser(Node& tree_node, token_iterator t_it); 58 | 59 | bool Match(boost::wave::token_id id); 60 | 61 | void Assignment(); 62 | void Expression(); 63 | void Expression1(); 64 | void Expression2(); 65 | void Expression3(); 66 | void Expression4(); 67 | void Expression5(); 68 | void Expression6(); 69 | void Expression7(); 70 | void Expression8(); 71 | 72 | bool PPCheckIdentifier(std::string id_str); 73 | token_iterator GetTokenPosition(); 74 | private: 75 | CondCategory condCat; 76 | //std::vector condStmt; 77 | Node* pNode; 78 | token_iterator it; 79 | MacroList_t macroList; 80 | }; 81 | 82 | #endif/*CONDPARSER_H*/ 83 | -------------------------------------------------------------------------------- /dummy_test/dm_dir/example.cpp: -------------------------------------------------------------------------------- 1 | #include "header1.h" 2 | 3 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_A_examplecpp_3_9) 4 | constexpr auto A = 100; 5 | #else 6 | #define A 100 7 | #endif 8 | 9 | 10 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE__c_examplecpp_5_9) 11 | template 12 | auto _c(_T1 i) -> decltype(i) 13 | { 14 | return i; 15 | } 16 | #else 17 | #define _c(i) i 18 | #endif 19 | 20 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE__a_examplecpp_6_9) 21 | template 22 | auto _a(_T1 i) -> decltype(i*i) 23 | { 24 | return i*i; 25 | } 26 | #else 27 | #define _a(i) i*i 28 | #endif 29 | 30 | 31 | #define CRYPTOPP_X86_ASM_AVAILABLE 32 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_FXY_examplecpp_9_9) 33 | template 34 | auto FXY(_T1 X, _T2 Y, _T3 Z) -> decltype(((X) + (Y))) 35 | { 36 | return ((X) + (Y)); 37 | } 38 | #else 39 | #define FXY(X,Y,Z) ((X) + (Y)) 40 | #endif 41 | 42 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_fun_examplecpp_10_9) 43 | 44 | auto fun() -> decltype(FXY(1,200,3)) 45 | { 46 | return FXY(1,200,3); 47 | } 48 | #else 49 | #define fun() FXY(1,200,3) 50 | #endif 51 | 52 | 53 | int i = fun(); 54 | int super(int i) 55 | { 56 | 57 | 58 | //variable 'j' referenced in macro INSIDE_FUN_SUPER 59 | //the transformation has to be carefully placed after the declaration of 'int j' 60 | int j = 10; 61 | 62 | return INSIDE_FUN_SUPER(10000, 4000); 63 | } 64 | int l = FXY((i+i),super(10),100); 65 | 66 | 67 | 68 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_proc_examplecpp_28_9) 69 | template 70 | void proc(_T1 && X, _T2 && Y) 71 | { 72 | X = FXY(X,Y,0); 73 | } 74 | 75 | #else 76 | #define proc(X,Y) { X = FXY(X,Y,0); } 77 | #endif 78 | 79 | #if defined(__cplusplus) && defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(USE_MSB_examplecpp_31_9) 80 | template 81 | auto MSB(_T1 x) -> decltype((((x) >> 24) & 0xffU) /* most significant byte */) 82 | { 83 | return (((x) >> 24) & 0xffU) /* most significant byte */; 84 | } 85 | #else 86 | #define MSB(x) (((x) >> 24) & 0xffU) /* most significant byte */ 87 | #endif 88 | 89 | 90 | 91 | #include 92 | 93 | int main() 94 | { 95 | int a1 = A; 96 | std::cout<<"\na1 = "< 30 | 31 | /** 32 | * @class UseCaseState 33 | * @details The class to keep track of the use case of macro in the code 34 | * The use case only corresponds to the macro usage in code and not in the 35 | * replacement list of the macro 36 | * @todo When the macro is nested within another macro during usage, if the 37 | * number of tokens in the identifier list of macro is not the same as the 38 | * tokens in use case then the string which records the use case 39 | * will not contain the complete identifier list 40 | */ 41 | class UseCaseState { 42 | private: 43 | typedef std::vector VecTokenIter_t; 44 | public: 45 | UseCaseState() 46 | : numParens(0), done(true) 47 | {} 48 | 49 | int PutToken(token_iterator tok_iter); 50 | 51 | std::pair Get() 52 | { return argIter; } 53 | 54 | void Init() 55 | { numParens = 0; done = true; arg.str(std::string()); argString.clear(); } 56 | 57 | bool DoneCollection() 58 | { return done; } 59 | 60 | void PutArgBegin(token_iterator tok_iter, PPMacro* p) 61 | { Init(); argIter.first = tok_iter; done = false; pp = p; } 62 | 63 | void PutArgEnd(token_iterator tok_iter) 64 | { argIter.second = tok_iter; } 65 | 66 | std::pair 67 | GetUseCase() 68 | { return argIter; } 69 | 70 | void MakeEntry(PPMacro* pp) 71 | { pp->set_use_case(argIter); } 72 | 73 | void SetUseCaseString(PPMacro* pp) 74 | { pp->set_use_case_string(argString); } 75 | 76 | // the following function is only for function like macro 77 | std::vector GetArgString() 78 | { return argString; } 79 | 80 | private: 81 | 82 | int numParens; 83 | bool done; 84 | std::pair argIter; 85 | std::vector argString; 86 | std::stringstream arg; 87 | PPMacro* pp; 88 | 89 | }; 90 | 91 | #endif /*USECASESTATE_H*/ 92 | -------------------------------------------------------------------------------- /ClangInterface/TrackMacro.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TRACK_MACRO_HPP 2 | #define TRACK_MACRO_HPP 3 | 4 | #include "map_utils.hpp" 5 | #include "vector_utils.hpp" 6 | #include "FunctionInfo.h" 7 | #include "MacroScopeClassifier.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | using namespace general_utilities; 19 | /* 20 | struct CollectedMacroInfo{ 21 | int defined_line; 22 | std::vector invoked_lines; 23 | PPOperation op; 24 | MacroCategory m_cat; 25 | CondCategory c_cat; 26 | MacroScopeCategory s_cat; 27 | }; 28 | */ 29 | //typedef std::map MacroStat_t; 30 | 31 | namespace clang{ 32 | //std::ostream& operator<<(std::ostream& os, const CollectedMacroInfo& cmi); 33 | class TrackMacro : public PPCallbacks 34 | { 35 | public: 36 | TrackMacro() 37 | :m_istat(NULL) 38 | {} 39 | 40 | ~TrackMacro() 41 | { delete m_istat; } 42 | 43 | /// PPCallback 44 | void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, 45 | SourceRange Range);//, MacroArgs* Args); in old version of 3.1 46 | 47 | /// PPCallback 48 | void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD); 49 | 50 | /// PPCallback 51 | bool FileNotFound(StringRef FileName, SmallVectorImpl& RecoveryPath); 52 | 53 | /// if the macro is local to the current file being processed 54 | bool MacroIsLocal(SourceLocation loc); 55 | 56 | void SetFileName(const std::string & f); 57 | 58 | const std::string& GetFileName(); 59 | 60 | void PrintStats(); 61 | 62 | void VerifyMacroScopeFast(std::mapconst & FunctionInfo); 63 | 64 | void VerifyMacroScope(std::mapconst & FunctionInfo); 65 | 66 | /// called everytime the file name is changed 67 | /// to get the file currently being processed 68 | void SetLocParams(); 69 | 70 | void SetCompilerInstance(const CompilerInstance* p); 71 | 72 | void InitializeMacroInvocationStat(); 73 | 74 | /// called by the MyASTConsumer class 75 | ASTMacroStat_t& GetMacroStat(); 76 | 77 | InvocationStat_t* GetInvocationStat(); 78 | //void CollectFunArgs(const MacroInfo* MI, SourceRange Range); 79 | /* MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroNameStr, 80 | MacroInfo *MI, 81 | SourceLocation &MacroEnd); 82 | */ 83 | private: 84 | std::string file_name; 85 | // contains all the information about macros in a file as collected by clang 86 | ASTMacroStat_t ASTMacroStat; 87 | //std::mapASTMacroStat; 88 | // contains the line numbers of all the macro invocations in a file 89 | InvocationStat_t* m_istat; 90 | const CompilerInstance *pci; 91 | SourceManager* sm; 92 | }; 93 | } 94 | #endif //TRACK_MACRO_HPP 95 | -------------------------------------------------------------------------------- /dummy_test/demac_cleanup/macro_stat.yaml: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | #This file contains the details of each macro present in the files processed 3 | #The file can be read by any yaml parser 4 | #The format is as follows: 5 | #macro 6 | # - m_id : identifier string 7 | # - m_cat: macro_category 8 | # - c_cat: if the replacement text maps to C++ expression then c_cat is complete otherwise partial 9 | # - d_cat: if the replacement text contains free variable(s) then d_cat is dependent otherwise closed 10 | ################################################################### 11 | - Total_Macros: 19 12 | - Total_Function_Like_Macros: 13 13 | - Total_Object_Like_Macros: 6 14 | - macro00000000: 15 | - m_id : depth0 16 | - m_cat: object_like 17 | - c_cat: complete 18 | - d_cat: closed 19 | 20 | - macro00000001: 21 | - m_id : a 22 | - m_cat: object_like 23 | - c_cat: complete 24 | - d_cat: closed 25 | 26 | - macro00000002: 27 | - m_id : b 28 | - m_cat: object_like 29 | - c_cat: complete 30 | - d_cat: closed 31 | 32 | - macro00000003: 33 | - m_id : _c(i) 34 | - m_cat: function_like 35 | - c_cat: complete 36 | - d_cat: closed 37 | 38 | - macro00000004: 39 | - m_id : _a(i) 40 | - m_cat: function_like 41 | - c_cat: complete 42 | - d_cat: closed 43 | 44 | - macro00000005: 45 | - m_id : CRYPTOPP_X86_ASM_AVAILABLE 46 | - m_cat: null_define 47 | - c_cat: complete 48 | - d_cat: closed 49 | 50 | - macro00000006: 51 | - m_id : FXY(X,Y,Z) 52 | - m_cat: function_like 53 | - c_cat: complete 54 | - d_cat: closed 55 | 56 | - macro00000007: 57 | - m_id : fun() 58 | - m_cat: function_like 59 | - c_cat: complete 60 | - d_cat: dependent 61 | 62 | - macro00000008: 63 | - m_id : INSIDE_FUN_SUPER(X,Y) 64 | - m_cat: function_like 65 | - c_cat: complete 66 | - d_cat: dependent 67 | 68 | - macro00000009: 69 | - m_id : proc(X,Y) 70 | - m_cat: function_like 71 | - c_cat: complete 72 | - d_cat: closed 73 | 74 | - macro00000010: 75 | - m_id : MSB(x) 76 | - m_cat: function_like 77 | - c_cat: complete 78 | - d_cat: closed 79 | 80 | - macro00000011: 81 | - m_id : SSB(x) 82 | - m_cat: function_like 83 | - c_cat: complete 84 | - d_cat: closed 85 | 86 | - macro00000012: 87 | - m_id : TSB(x) 88 | - m_cat: function_like 89 | - c_cat: complete 90 | - d_cat: closed 91 | 92 | - macro00000013: 93 | - m_id : LSB(x) 94 | - m_cat: function_like 95 | - c_cat: complete 96 | - d_cat: closed 97 | 98 | - macro00000014: 99 | - m_id : INSIDE_FUN(X) 100 | - m_cat: function_like 101 | - c_cat: complete 102 | - d_cat: closed 103 | 104 | - macro00000015: 105 | - m_id : header11_macro 106 | - m_cat: object_like 107 | - c_cat: complete 108 | - d_cat: closed 109 | 110 | - macro00000016: 111 | - m_id : header12_macro 112 | - m_cat: object_like 113 | - c_cat: complete 114 | - d_cat: closed 115 | 116 | - macro00000017: 117 | - m_id : header1_macro(x,y) 118 | - m_cat: function_like 119 | - c_cat: complete 120 | - d_cat: closed 121 | 122 | - macro00000018: 123 | - m_id : header3_macro(x,y) 124 | - m_cat: function_like 125 | - c_cat: complete 126 | - d_cat: closed 127 | 128 | -------------------------------------------------------------------------------- /RlParser.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef RLPARSER_H 24 | #define RLPARSER_H 25 | 26 | 27 | /** 28 | * @file RlParser.h 29 | * @brief parses and classifies the replacement list of the macro and 30 | * returns the result to the ReplacementList class. 31 | * @version 1.0 32 | * @author Aditya Kumar 33 | * @note 34 | * compiles with g++-4.5 or higher, 35 | * for compiling pass -std=c++0x to the compiler 36 | */ 37 | 38 | #include "RlCategory.h" 39 | #include "DemacBoostWaveIncludes.h" 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | /** 46 | * @class DemacroficationScheme 47 | * @brief forward declaration 48 | */ 49 | struct DemacroficationScheme; 50 | 51 | 52 | /// @brief forward declaration 53 | class ReplacementList; 54 | 55 | 56 | /** 57 | * @class RlParser 58 | * @brief The parser of replacement list of the macro 59 | */ 60 | class RlParser { 61 | 62 | public: 63 | RlParser(DemacroficationScheme const& demacrofication_scheme, 64 | std::ostream& log_file); 65 | void Parse(ReplacementList& rl); 66 | void Parser(std::vector::iterator beg, 67 | std::vector::iterator term); 68 | 69 | bool Match(boost::wave::token_id id); 70 | void ExpressionStatement(); 71 | void Assignment(); 72 | void Expression(); 73 | void Expression1(); 74 | void Expression2(); 75 | void Expression3(); 76 | void Expression4(); 77 | void Expression5(); 78 | void Expression6(); 79 | void Expression7(); 80 | void Expression8(); 81 | bool IsRejectPredefinedMacro(std::string str) const; 82 | void FillFormattedRL(token_type tok); 83 | private: 84 | std::vector funArgId; 85 | std::vector::iterator it; 86 | std::vector::iterator end; 87 | //formatted replacement list string 88 | std::string rl_str_formatted; 89 | //contains identifiers in the ReplacementList 90 | std::set rl_idlist; 91 | RlCCat rl_ccat; 92 | RlDCat rl_dcat; 93 | RlTokType rl_ttype; 94 | //information for the parser and demacrofier on how to demacrofy 95 | DemacroficationScheme const* pDemacroficationScheme; 96 | //log file to store all the errors and warnings etc. 97 | std::ostream& logFile; 98 | }; 99 | 100 | #endif /*RLPARSER_H*/ 101 | -------------------------------------------------------------------------------- /general_utilities/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERAL_UTILITIES_DEBUG_H 2 | #define GENERAL_UTILITIES_DEBUG_H 3 | 4 | // This file sets up debugging infrastructure. 5 | // This is mainly inspired from the LLVMs (www.llvm.org) method of debugging. 6 | 7 | #ifndef NDEBUG 8 | #define DEBUG(ARG) do { ARG; } while(0) 9 | #else 10 | #define DEBUG(ARG) 11 | #endif 12 | 13 | #ifdef DEBUG_CLEANUP_CODE_PRINT 14 | #define DEBUG_CLEANUP_CODE(ARG) DEBUG(ARG) 15 | #else 16 | #define DEBUG_CLEANUP_CODE(ARG) 17 | #endif 18 | 19 | #ifdef DEBUG_CONDITIONALS_PRINT 20 | #define DEBUG_CONDITIONALS(ARG) DEBUG(ARG) 21 | #else 22 | #define DEBUG_CONDITIONALS(ARG) 23 | #endif 24 | 25 | #ifdef DEBUG_CONDITIONALS1_PRINT 26 | #define DEBUG_CONDITIONALS1(ARG) DEBUG(ARG) 27 | #else 28 | #define DEBUG_CONDITIONALS1(ARG) 29 | #endif 30 | 31 | #ifdef DEBUG_PARSER_PRINT 32 | #define DEBUG_PARSER(ARG) DEBUG(ARG) 33 | #else 34 | #define DEBUG_PARSER(ARG) 35 | #endif 36 | 37 | #ifdef CLANG_AST_DEBUG_PRINT 38 | #define CLANG_AST_DEBUG(ARG) DEBUG(ARG) 39 | #else 40 | #define CLANG_AST_DEBUG(ARG) 41 | #endif 42 | 43 | #ifdef DEBUG_RLPARSER_PRINT 44 | #define DEBUG_RLPARSER(ARG) DEBUG(ARG) 45 | #else 46 | #define DEBUG_RLPARSER(ARG) 47 | #endif 48 | 49 | #ifdef DEBUG_RLPARSER2_PRINT 50 | #define DEBUG_RLPARSER2(ARG) DEBUG(ARG) 51 | #else 52 | #define DEBUG_RLPARSER2(ARG) 53 | #endif 54 | 55 | #ifdef DEBUG_DEMACROFIER_PRINT 56 | #define DEBUG_DEMACROFIER(ARG) DEBUG(ARG) 57 | #else 58 | #define DEBUG_DEMACROFIER(ARG) 59 | #endif 60 | 61 | #ifdef DEBUG_SUGGESTION_PRINT 62 | #define DEBUG_SUGGESTION(ARG) DEBUG(ARG) 63 | #else 64 | #define DEBUG_SUGGESTION(ARG) 65 | #endif 66 | 67 | #ifdef DEBUG_TREE_PRINT 68 | #define DEBUG_TREE(ARG) DEBUG(ARG) 69 | #else 70 | #define DEBUG_TREE(ARG) 71 | #endif 72 | 73 | #ifdef DEBUG_MACRO_USE_CASE_PRINT 74 | #define DEBUG_MACRO_USE_CASE(ARG) DEBUG(ARG) 75 | #else 76 | #define DEBUG_MACRO_USE_CASE(ARG) 77 | #endif 78 | 79 | #ifdef ENABLE_WARNING_PRINT 80 | #define ENABLE_WARNING(ARG) DEBUG(ARG) 81 | #else 82 | #define ENABLE_WARNING(ARG) 83 | #endif 84 | 85 | #ifdef DEBUG_MACRO_USE_CASE_PRINT 86 | #define DEBUG_MACRO_USE_CASE(ARG) DEBUG(ARG) 87 | #else 88 | #define DEBUG_MACRO_USE_CASE(ARG) 89 | #endif 90 | 91 | #ifdef DEBUG_MACRO_CLASS_PRINT 92 | #define DEBUG_MACRO_CLASS(ARG) DEBUG(ARG) 93 | #else 94 | #define DEBUG_MACRO_CLASS(ARG) 95 | #endif 96 | 97 | #ifdef DEBUG_MACRO_DEPENDENCY_PRINT 98 | #define DEBUG_MACRO_DEPENDENCY(ARG) DEBUG(ARG) 99 | #else 100 | #define DEBUG_MACRO_DEPENDENCY(ARG) 101 | #endif 102 | 103 | #ifdef DEBUG_ASTCONSUMER_PRINT 104 | #define DEBUG_ASTCONSUMER(ARG) DEBUG(ARG) 105 | #else 106 | #define DEBUG_ASTCONSUMER(ARG) 107 | #endif 108 | 109 | #include 110 | #include 111 | 112 | // This is llvm style debug printer. 113 | extern std::ostream *dbg_stream; 114 | std::ostream& dbgs(); 115 | void set_dbg_stream(std::ostream &os); 116 | 117 | template 118 | inline void PrintElements(std::ostream& os, const T& t) 119 | { 120 | std::for_each(t.begin(), t.end(), [&os](typename T::value_type v){ 121 | os << v << " "; 122 | }); 123 | os << "\n"; 124 | } 125 | 126 | template 127 | inline void PrintPointees(std::ostream& os, const T& t) 128 | { 129 | std::for_each(t.begin(), t.end(), [&os](typename T::value_type v){ 130 | os << *v << " "; 131 | }); 132 | os << "\n"; 133 | } 134 | 135 | #endif // GENERAL_UTILITIES_DEBUG_H 136 | -------------------------------------------------------------------------------- /ConfigScheme.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef CONFIGSCHEME_H 24 | #define CONFIGSCHEME_H 25 | 26 | /** 27 | * @file ConfigScheme.h 28 | * @class ConfigScheme 29 | * @note defines the specifications for demacrofication 30 | * 1. To demacrofy one macro at a time or one file at a time 31 | * 2. Enable the warning flag or not 32 | * 3. Where should the errors to be put to stderr or stdout or to some file 33 | * 4. Where should the warnings to be put to stderr or stdout or to some file 34 | * 5. Whether to demacrofy the configurational macros or not 35 | * 6. Whether to invoke compiler/make command for each file demacrofied or not 36 | */ 37 | 38 | #include "FileManagerScheme.h" 39 | #include "DemacroficationScheme.h" 40 | #include "BuildScheme.h" 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | 48 | class ConfigScheme { 49 | 50 | public: 51 | ConfigScheme(); 52 | ~ConfigScheme(); 53 | void SetFileManagerScheme(std::vectorconst& input_files, 54 | std::vectorconst& output_files, 55 | std::vectorconst& search_paths, 56 | std::string const& input_directory, 57 | std::string const& output_directory, 58 | std::string const& backup_directory, 59 | std::string const& cleanup_directory, 60 | std::string const& validator_file, 61 | std::ostream* log_file, 62 | std::ostream* stat_file, 63 | std::ostream* macro_list_file 64 | ); 65 | /// @todo demacrofication granularity to be implemented 66 | void SetDemacroficationScheme(std::string const& demac_gran, 67 | std::vector const& mac_prev_demac, 68 | bool enable_warning, 69 | std::string const& global_mac_raw, 70 | std::string const& global_mac_formatted, 71 | bool multiple_definitions, 72 | bool cleanup 73 | ); 74 | void SetBuildScheme(std::string const& make_command); 75 | FileManagerScheme& GetFileManagerScheme(); 76 | DemacroficationScheme& GetDemacroficationScheme(); 77 | BuildScheme& GetBuildScheme(); 78 | 79 | private: 80 | FileManagerScheme* pFileManagerScheme; 81 | DemacroficationScheme* pDemacroficationScheme; 82 | BuildScheme* pBuildScheme; 83 | 84 | }; 85 | #endif /*CONFIGSCHEME_H*/ 86 | -------------------------------------------------------------------------------- /dummy_test/ConfigFile.cfg: -------------------------------------------------------------------------------- 1 | ################### input files list ################################# 2 | ############### source files ######################################### 3 | input-file = example.cpp 4 | ############### header files ######################################### 5 | input-file = header1.h 6 | input-file = header2.h 7 | 8 | ###################################################################### 9 | 10 | ################## output files list ################################# 11 | ################## source files ###################################### 12 | output-file = example.cpp 13 | ################## heaer files ###################################### 14 | output-file = header1.h 15 | output-file = header2.h 16 | ###################################################################### 17 | 18 | ################## log files ######################################## 19 | macro-stat-file = macro_stat.yaml 20 | stat-file = demacrofied_macro_stat.yaml 21 | validator-file = Defined.h 22 | global-macros-formatted = gMacros.dat 23 | log-file = log.yaml 24 | 25 | ################## directory paths ################################### 26 | input-directory = . 27 | output-directory = dm_dir 28 | cleanup-directory = demac_cleanup 29 | 30 | ############### macros that prevent demacrofication ################## 31 | ignore-macros = __FILE__ 32 | ignore-macros = __BASE_FILE__ 33 | ignore-macros = __LINE__ 34 | ignore-macros = __INCLUDE_LEVEL__ 35 | ignore-macros = __TIMESTAMP__ 36 | ignore-macros = __func__ 37 | ignore-macros = __FUNCTION__ 38 | ignore-macros = __declspec 39 | ignore-macros = __attribute__ 40 | 41 | ################## other settingss ################################### 42 | enable-warning = false 43 | no-translate = false 44 | mul-def = false 45 | #when the cleanup is set to true, the output file names corresponds to 46 | #the files with cleaned up output but relative to the cleanup-directory 47 | #cleanup = true 48 | cleanup = false 49 | 50 | 51 | ################## search paths for the clang front end ############## 52 | ###### add/remove the search paths as per the requirements ######## 53 | #clang specific include 54 | #it contains headers with all the standard(platform-specific) definitions etc. 55 | search-path = /home/hiraditya/work/llvm/install/lib/clang/3.7.1/include 56 | 57 | #platform specific 58 | #32 bit 59 | #search-path = /usr/include/i386-linux-gnu 60 | #search-path = /usr/lib/gcc/i686-linux-gnu/4.9 61 | 62 | #General includes 63 | # search-path = /usr/include 64 | # search-path = /usr/include/linux 65 | # 66 | 67 | # The easiest way to get this option is to do g++ -v test.cpp 68 | # and copy those include paths here. 69 | search-path = /usr/include/c++/4.9 70 | search-path = /usr/include/x86_64-linux-gnu/c++/4.9 71 | search-path = /usr/include/c++/4.9/backward 72 | search-path = /usr/lib/gcc/x86_64-linux-gnu/4.9/include 73 | search-path = /usr/local/include 74 | search-path = /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed 75 | search-path = /usr/include/x86_64-linux-gnu 76 | search-path = /usr/include 77 | 78 | 79 | #32 bit 80 | #search-path = /usr/include/c++/4.9/i686-linux-gnu 81 | #search-path = /usr/include/c++/4.9/i686-linux-gnu/64 82 | 83 | #for local libs e.g. boost 84 | #search-path = /usr/local/include 85 | 86 | #project specific includes 87 | #to be added at the end 88 | #(clang searches from first search-path to the last search-path) 89 | search-path = /home/hiraditya/work/demacrofier/cpp2cxx/dummy_test/dir 90 | 91 | ################# unused features ################################### 92 | make-command = make 93 | demacrofication-granularity = OneFileAtATime 94 | backup-directory = demac_backup 95 | -------------------------------------------------------------------------------- /ReplacementList.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef REPLACEMENTLIST_H 24 | #define REPLACEMENTLIST_H 25 | 26 | /** 27 | * @file ReplacementList.h 28 | * @brief responsible for housekeeping of the replacement list of macro. 29 | * It calls the RlParser class which parses and classifies the replacement list. 30 | * @version 1.0 31 | * @author Aditya Kumar 32 | * @note 33 | * compiles with g++-4.5 or higher, 34 | * for compiling pass -std=c++0x to the compiler 35 | */ 36 | 37 | #include "RlCategory.h" 38 | #include "DemacBoostWaveIncludes.h" 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | /// @brief forward declaration 46 | class RlParser; 47 | 48 | /** 49 | * @class ReplacementList 50 | * @brief class to keep all the details of replacement list of a macro 51 | * This class is a member variable of the PPMacro class 52 | */ 53 | class ReplacementList { 54 | 55 | public: 56 | //use token_iterator const& 57 | ReplacementList(); 58 | typedef std::vector >vpTokInt; 59 | void set_replacement_list(token_type tok); 60 | void set_replacement_list_str(std::string const& str, vpTokInt argId); 61 | void set_replacement_list_category(RlParser & rl_parser); 62 | /// set by the dependency analyzer at a later stage 63 | void set_replacement_list_dependency_category(bool c); 64 | std::string get_replacement_list_str() const; 65 | std::string const& get_formatted_replacement_list_str() const; 66 | std::string const& get_replacement_list_str_with_comments() const; 67 | std::vector const& get_replacement_list_tokens() const; 68 | 69 | RlDCat 70 | get_replacement_list_dependency_category() const; 71 | 72 | RlCCat 73 | get_replacement_list_closure_category() const; 74 | 75 | RlTokType const& 76 | get_replacement_list_token_type() const; 77 | 78 | RlTokType& 79 | get_replacement_list_token_type(); 80 | 81 | std::list 82 | get_replacement_list_idlist() const; 83 | 84 | private: 85 | /** friend class 86 | * @class RlParser 87 | */ 88 | friend class RlParser; 89 | std::vector funArgId; 90 | 91 | /// tokens of replacement_list 92 | std::vector rl_tokens; 93 | 94 | /// replacement list string 95 | std::string rl_str; 96 | 97 | /// formatted replacement list string 98 | std::string rl_str_formatted; 99 | 100 | /// identifiers in the replacement list of the macro 101 | std::set rl_idlist; 102 | 103 | RlCCat rl_ccat; 104 | RlDCat rl_dcat; 105 | RlTokType rl_ttype; 106 | }; 107 | 108 | #endif /* REPLACEMENTLIST_H */ 109 | -------------------------------------------------------------------------------- /dummy_test/demac_cleanup/example.cpp: -------------------------------------------------------------------------------- 1 | #include "header1.h" 2 | 3 | 4 | /** Demacrofication for the macro depth0 with unique identifier USE_depth0_examplecpp_3_9*/ 5 | constexpr auto depth0 = 0; 6 | 7 | /** Demacrofication for the macro a with unique identifier USE_a_examplecpp_4_9*/ 8 | constexpr auto a = 100; 9 | 10 | /** Demacrofication for the macro b with unique identifier USE_b_examplecpp_5_9*/ 11 | constexpr auto b = 200; 12 | 13 | 14 | /** Demacrofication for the macro _c with unique identifier USE__c_examplecpp_7_9*/ 15 | template 16 | auto _c(_T1 i) -> decltype(i) 17 | { 18 | return i; 19 | } 20 | 21 | /** Demacrofication for the macro _a with unique identifier USE__a_examplecpp_8_9*/ 22 | template 23 | auto _a(_T1 i) -> decltype(i*i) 24 | { 25 | return i*i; 26 | } 27 | 28 | #define CRYPTOPP_X86_ASM_AVAILABLE 29 | 30 | /** Demacrofication for the macro FXY with unique identifier USE_FXY_examplecpp_11_9*/ 31 | template 32 | auto FXY(_T1 X, _T2 Y, _T3 Z) -> decltype(((X) + (Y))) 33 | { 34 | return ((X) + (Y)); 35 | } 36 | 37 | /** Demacrofication for the macro fun with unique identifier USE_fun_examplecpp_12_9*/ 38 | 39 | auto fun() -> decltype(FXY(1,200,3)) 40 | { 41 | return FXY(1,200,3); 42 | } 43 | 44 | int i = fun(); 45 | int super(int i) 46 | { 47 | 48 | 49 | //variable 'j' referenced in macro INSIDE_FUN_SUPER 50 | //the transformation has to be carefully placed after the declaration of 'int j' 51 | int j = 10; 52 | 53 | 54 | /** Demacrofication for the macro INSIDE_FUN_SUPER with unique identifier USE_INSIDE_FUN_SUPER_examplecpp_18_9*/ 55 | auto INSIDE_FUN_SUPER = [&j](decltype(10000) X, decltype( 4000) Y) { return X+100 + j; }; 56 | return INSIDE_FUN_SUPER(10000, 4000); 57 | } 58 | int l = FXY((i+i),super(10),100); 59 | 60 | int aPtr[] = {1,2,3,4,5,6,7,8,9,10}; 61 | int cPtr[] = {1,2,3,4,5,6,7,8,9,10}; 62 | 63 | 64 | 65 | /** Demacrofication for the macro proc with unique identifier USE_proc_examplecpp_32_9*/ 66 | template 67 | void proc(_T1 && X, _T2 && Y) 68 | { 69 | FXY(X,Y,0); 70 | } 71 | 72 | 73 | /** Demacrofication for the macro MSB with unique identifier USE_MSB_examplecpp_35_9*/ 74 | template 75 | auto MSB(_T1 x) -> decltype((((x) >> 24) & 0xffU) /* most significant byte */) 76 | { 77 | return (((x) >> 24) & 0xffU) /* most significant byte */; 78 | } 79 | 80 | 81 | /** Demacrofication for the macro SSB with unique identifier USE_SSB_examplecpp_36_9*/ 82 | template 83 | auto SSB(_T1 x) -> decltype((((x) >> 16) & 0xffU) /* second in significance */) 84 | { 85 | return (((x) >> 16) & 0xffU) /* second in significance */; 86 | } 87 | 88 | 89 | /** Demacrofication for the macro TSB with unique identifier USE_TSB_examplecpp_37_9*/ 90 | template 91 | auto TSB(_T1 x) -> decltype((((x) >> 8) & 0xffU) /* third in significance */) 92 | { 93 | return (((x) >> 8) & 0xffU) /* third in significance */; 94 | } 95 | 96 | 97 | /** Demacrofication for the macro LSB with unique identifier USE_LSB_examplecpp_38_9*/ 98 | template 99 | auto LSB(_T1 x) -> decltype((((x) ) & 0xffU) /* least significant byte */) 100 | { 101 | return (((x) ) & 0xffU) /* least significant byte */; 102 | } 103 | 104 | 105 | #include 106 | 107 | int main() 108 | { 109 | int a1 = a; 110 | int b1 = b; 111 | int c1 = 'c'; 112 | 113 | //std::cout< 28 | #include 29 | 30 | ReplacementList::ReplacementList() 31 | :rl_ccat(RlCCat::open), 32 | rl_dcat(RlDCat::dependent) 33 | { } 34 | 35 | void ReplacementList::set_replacement_list(token_type tok) 36 | { 37 | rl_tokens.push_back(tok); 38 | // std::cout<<"ReplacementList: "<<(*it).get_value()< p_ti) { 48 | this->funArgId.push_back(p_ti.first); 49 | }); 50 | } 51 | // std::cout<<"repl_string: "< const& 91 | ReplacementList::get_replacement_list_tokens() const 92 | { 93 | return rl_tokens; 94 | } 95 | 96 | RlDCat 97 | ReplacementList::get_replacement_list_dependency_category() const 98 | { 99 | return rl_dcat; 100 | } 101 | 102 | RlCCat 103 | ReplacementList::get_replacement_list_closure_category() const 104 | { 105 | return rl_ccat; 106 | } 107 | 108 | RlTokType const& 109 | ReplacementList::get_replacement_list_token_type() const 110 | { 111 | return rl_ttype; 112 | } 113 | 114 | /// called by the PPMacro class 115 | RlTokType& 116 | ReplacementList::get_replacement_list_token_type() 117 | { 118 | return rl_ttype; 119 | } 120 | 121 | 122 | std::list 123 | ReplacementList::get_replacement_list_idlist() const 124 | { 125 | std::list id_list; 126 | std::for_each(rl_idlist.begin(),rl_idlist.end(), 127 | [&id_list](token_type tok) { 128 | id_list.push_back(tok); 129 | }); 130 | return id_list; 131 | } 132 | -------------------------------------------------------------------------------- /MacroScopeClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef MACROSCOPECLASSIFIER_H 2 | #define MACROSCOPECLASSIFIER_H 3 | // (c) Copyright 4 | // ALL RIGHTS RESERVED 5 | /** 6 | * @file MacroScopeClassifier.h 7 | * @brief defines various classification criteria for macros 8 | * @version 1.0 9 | * @author Aditya Kumar 10 | * @details 11 | * compiles with g++-4.5 or higher, 12 | * for compiling pass -std=c++0x to the compiler 13 | */ 14 | 15 | #include 16 | /** 17 | * @enum PPOperation 18 | */ 19 | enum class PPOperation 20 | { 21 | define, 22 | undef, 23 | conditional, 24 | includes, 25 | pragma, 26 | warning, 27 | line, 28 | error 29 | }; 30 | 31 | inline std::ostream& operator<<(std::ostream& os, PPOperation const& oper) 32 | { 33 | switch(oper){ 34 | case PPOperation::define: 35 | os<<"define"; 36 | break; 37 | case PPOperation::undef: 38 | os<<"undef"; 39 | break; 40 | case PPOperation::conditional: 41 | os<<"conditional"; 42 | break; 43 | case PPOperation::includes: 44 | os<<"includes"; 45 | break; 46 | case PPOperation::pragma: 47 | os<<"pragma"; 48 | break; 49 | case PPOperation::warning: 50 | os<<"warning"; 51 | break; 52 | case PPOperation::line: 53 | os<<"line"; 54 | break; 55 | case PPOperation::error: 56 | os<<"error"; 57 | break; 58 | default: 59 | os<<"unknown"; 60 | break; 61 | } 62 | return os; 63 | } 64 | 65 | /** 66 | * @enum MacroCategory 67 | */ 68 | enum class MacroCategory 69 | { 70 | none, 71 | null_define,//#define X i.e. without replacement_list 72 | object_like, 73 | function_like, 74 | variadic 75 | }; 76 | 77 | inline std::ostream& operator<<(std::ostream& os, MacroCategory const& m_cat ) 78 | { 79 | switch(m_cat){ 80 | case MacroCategory::none: 81 | os<<"none"; 82 | break; 83 | case MacroCategory::null_define: 84 | os<<"null_define"; 85 | break; 86 | case MacroCategory::object_like: 87 | os<<"object_like"; 88 | break; 89 | case MacroCategory::function_like: 90 | os<<"function_like"; 91 | break; 92 | case MacroCategory::variadic: 93 | os<<"variadic"; 94 | break; 95 | } 96 | return os; 97 | } 98 | 99 | /** 100 | * @enum MacroScopeCategory 101 | */ 102 | struct MacroScopeCategory 103 | { 104 | MacroScopeCategory() 105 | :predefined(false), 106 | local(true), 107 | inside_function(false), 108 | inside_class(false) 109 | { } 110 | bool predefined; 111 | bool local; 112 | bool inside_function; 113 | bool inside_class; 114 | }; 115 | inline std::ostream& operator<<(std::ostream& os, MacroScopeCategory const& m_cat ) 116 | { 117 | if(m_cat.predefined) 118 | os<<"predefined\t"; 119 | if(m_cat.local) 120 | os<<"local\t"; 121 | if(m_cat.inside_function) 122 | os<<"inside_function\t"; 123 | if(m_cat.inside_class) 124 | os<<"inside_class\t"; 125 | else 126 | os<<"Not classified\t"; 127 | return os; 128 | } 129 | 130 | /* 131 | inline std::ostream& operator<<(std::ostream& os, MacroScopeCategory const& m_cat ) 132 | { 133 | switch(m_cat){ 134 | case MacroScopeCategory::predefined: 135 | os<<"predefine"; 136 | break; 137 | case MacroScopeCategory::local: 138 | os<<"local"; 139 | break; 140 | case MacroScopeCategory::inside_function: 141 | os<<"inside_function"; 142 | break; 143 | case MacroScopeCategory::inside_class: 144 | os<<"inside_class"; 145 | break; 146 | } 147 | return os; 148 | }*/ 149 | 150 | /** 151 | * @enum CondCategory 152 | */ 153 | enum class CondCategory 154 | { 155 | config, 156 | local 157 | }; 158 | inline std::ostream& operator<<(std::ostream& os, CondCategory const& c_cat ) 159 | { 160 | switch(c_cat){ 161 | case CondCategory::config: 162 | os<<"config"; 163 | break; 164 | case CondCategory::local: 165 | os<<"local"; 166 | break; 167 | } 168 | return os; 169 | } 170 | 171 | #endif // MACROSCOPECLASSIFIER_H 172 | -------------------------------------------------------------------------------- /Overseer.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef OVERSEER_H 24 | #define OVERSEER_H 25 | 26 | /** 27 | * @file Overseer.h 28 | * @brief the class which is responsible for regulating the 29 | * functionality of all the classes. It takes the ConfigScheme from the 30 | * Main and defines the operations for Parser, Demacrofier and FileManager 31 | * @version 1.0 32 | * @author Aditya Kumar 33 | * @note 34 | * compiles with g++-4.5 or higher, 35 | * for compiling pass -std=c++0x to the compiler 36 | */ 37 | #include "FileManagerScheme.h" 38 | #include "ConfigScheme.h" 39 | #include "ASTConsumer.hpp" 40 | 41 | #include 42 | #include 43 | 44 | /// @todo for error handling each place where error is caught 45 | /// the error message will be sent to the overseer class and this class will 46 | /// log the error according to the demacrofication scheme 47 | 48 | /** 49 | * @class ConfigScheme 50 | * forward declaration 51 | */ 52 | //class ConfigScheme; 53 | /** 54 | * @class FileManager 55 | * forward declaration 56 | */ 57 | class FileManager; 58 | 59 | /** 60 | * @class Parser 61 | * forward declaration 62 | */ 63 | class Parser; 64 | 65 | /** 66 | * @class MacTree 67 | * forward declaration 68 | */ 69 | class MacTree; 70 | 71 | /** 72 | * @class Overseer 73 | * @brief the class responsible for managing the whole project, 74 | * transferring controls to various other classes and getting 75 | * their outputs. 76 | */ 77 | class Overseer { 78 | public: 79 | Overseer(ConfigScheme& config_scheme); 80 | ~Overseer(); 81 | 82 | void ConfigureFileManager(); 83 | /** 84 | * @function StartProcessing 85 | * @details processing is to be done in the following steps 86 | * 1. configure file manager 87 | * 2. get one file from file manager 88 | * 3. call the parser 89 | * 4. get the macro count 90 | * 5. run the dependency analyzer,print total order 91 | * 6. call the demacrofier as per the scheme 92 | * 7. update the demacrofied string to the file manager 93 | * 8. call the build class 94 | * 9. goto step2 95 | * 10. catch any errors 96 | */ 97 | void StartProcessing(bool demacrofy); 98 | void RunParser(std::string file_name); 99 | void RunDependencyAnalyzer(); 100 | void PrintTotalOrder(); 101 | void RunDemacrofier(); 102 | void UpdateFileManager(); 103 | void WriteOutputFile(std::ostream& os) const; 104 | //void GetInformationFromExternalSource(const std::string& filename); 105 | void GenerateExternalASTHandler(const std::string& filename); 106 | //void GenerateExternalASTHandler(); 107 | std::ostream& GetLogFile(); 108 | std::ostream& GetMacroStatFile(); 109 | std::ostream& GetStatFile(); 110 | std::vector const& GetInputFiles(); 111 | DemacroficationScheme& GetDemacroficationScheme(); 112 | FileManagerScheme& GetFileManagerScheme(); 113 | 114 | 115 | 116 | private: 117 | ConfigScheme& configScheme; 118 | FileManager* pFileManager; 119 | Parser* pParser; 120 | MacTree const* pMacTree; 121 | MyASTConsumer* pASTConsumer; 122 | /// \brief holds information returned from clang AST 123 | ASTMacroStat_t ASTMacroStat; 124 | }; 125 | 126 | #endif /*OVERSEER_H*/ 127 | -------------------------------------------------------------------------------- /ConfigScheme.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #include "ConfigScheme.h" 24 | #include 25 | ConfigScheme::ConfigScheme() 26 | { 27 | pFileManagerScheme = new FileManagerScheme; 28 | pDemacroficationScheme = new DemacroficationScheme; 29 | pBuildScheme = new BuildScheme; 30 | } 31 | 32 | ConfigScheme::~ConfigScheme() 33 | { 34 | delete pFileManagerScheme; 35 | delete pDemacroficationScheme; 36 | delete pBuildScheme; 37 | } 38 | 39 | void ConfigScheme::SetFileManagerScheme(std::vectorconst& input_files, 40 | std::vectorconst& output_files, 41 | std::vectorconst& search_paths, 42 | std::string const& input_directory, 43 | std::string const& output_directory, 44 | std::string const& backup_directory, 45 | std::string const& cleanup_directory, 46 | std::string const& validator_file, 47 | std::ostream* log_file, 48 | std::ostream* demacrofied_macro_stat_file, 49 | std::ostream* macro_stat_file 50 | ) 51 | { 52 | pFileManagerScheme->inputFiles = input_files; 53 | pFileManagerScheme->outputFiles = output_files; 54 | pFileManagerScheme->searchPaths = search_paths; 55 | pFileManagerScheme->inputDirectory = input_directory; 56 | pFileManagerScheme->outputDirectory = output_directory; 57 | pFileManagerScheme->backupDirectory = backup_directory; 58 | pFileManagerScheme->cleanup_directory = cleanup_directory; 59 | pFileManagerScheme->validator_file = validator_file; 60 | pFileManagerScheme->pLogFile = log_file; 61 | pFileManagerScheme->pDemacrofiedMacroStatFile = demacrofied_macro_stat_file; 62 | pFileManagerScheme->pMacroStatFile = macro_stat_file; 63 | } 64 | 65 | void ConfigScheme::SetDemacroficationScheme(std::string const& demac_gran, 66 | std::vector const& mac_prev_demac, 67 | bool enable_warning, 68 | std::string const& global_mac_raw, 69 | std::string const& global_mac_formatted, 70 | bool multiple_definitions, 71 | bool cleanup 72 | ) 73 | { 74 | pDemacroficationScheme->demacroficationGranularity = demac_gran; 75 | pDemacroficationScheme->enableWarningFlag = enable_warning; 76 | pDemacroficationScheme->globalMacrosRaw = global_mac_raw; 77 | pDemacroficationScheme->globalMacrosFormatted = global_mac_formatted; 78 | std::for_each(mac_prev_demac.begin(),mac_prev_demac.end(), 79 | [this](std::string const& str) { 80 | this->pDemacroficationScheme->macrosPreventingDemacrofication.insert(str); 81 | }); 82 | pDemacroficationScheme->multipleDefinitions = multiple_definitions; 83 | pDemacroficationScheme->performCleanup = cleanup; 84 | 85 | if(cleanup) 86 | pDemacroficationScheme->validatorMap.InitValidatorMap(pFileManagerScheme->validator_file); 87 | } 88 | 89 | void ConfigScheme::SetBuildScheme(std::string const& make_command) 90 | { 91 | pBuildScheme->makeCommand = make_command; 92 | } 93 | 94 | FileManagerScheme& ConfigScheme::GetFileManagerScheme() 95 | { 96 | return *pFileManagerScheme; 97 | } 98 | 99 | DemacroficationScheme& ConfigScheme::GetDemacroficationScheme() 100 | { 101 | return *pDemacroficationScheme; 102 | } 103 | 104 | BuildScheme& ConfigScheme::GetBuildScheme() 105 | { 106 | return *pBuildScheme; 107 | } 108 | -------------------------------------------------------------------------------- /gMacros.dat: -------------------------------------------------------------------------------- 1 | _FORTIFY_SOURCE 2 | 2 3 | _GNU_SOURCE 4 | 1 5 | __BIGGEST_ALIGNMENT__ 6 | 16 7 | __CHAR16_TYPE__ 8 | short unsigned int 9 | __CHAR32_TYPE__ 10 | unsigned int 11 | __CHAR_BIT__ 12 | 8 13 | __DBL_DENORM_MIN__ 14 | 4.9406564584124654e-324 15 | __DBL_DIG__ 16 | 15 17 | __DBL_EPSILON__ 18 | 2.2204460492503131e-16 19 | __DBL_HAS_DENORM__ 20 | 1 21 | __DBL_HAS_INFINITY__ 22 | 1 23 | __DBL_HAS_QUIET_NAN__ 24 | 1 25 | __DBL_MANT_DIG__ 26 | 53 27 | __DBL_MAX_10_EXP__ 28 | 308 29 | __DBL_MAX_EXP__ 30 | 1024 31 | __DBL_MAX__ 32 | 1.7976931348623157e+308 33 | __DBL_MIN_10_EXP__ 34 | (-307) 35 | __DBL_MIN_EXP__ 36 | (-1021) 37 | __DBL_MIN__ 38 | 2.2250738585072014e-308 39 | __DEC128_EPSILON__ 40 | 1E-33DL 41 | __DEC128_MANT_DIG__ 42 | 34 43 | __DEC128_MAX_EXP__ 44 | 6145 45 | __DEC128_MAX__ 46 | 9.999999999999999999999999999999999E6144DL 47 | __DEC128_MIN_EXP__ 48 | (-6142) 49 | __DEC128_MIN__ 50 | 1E-6143DL 51 | __DEC128_SUBNORMAL_MIN__ 52 | 0.000000000000000000000000000000001E-6143DL 53 | __DEC32_EPSILON__ 54 | 1E-6DF 55 | __DEC32_MANT_DIG__ 56 | 7 57 | __DEC32_MAX_EXP__ 58 | 97 59 | __DEC32_MAX__ 60 | 9.999999E96DF 61 | __DEC32_MIN_EXP__ 62 | (-94) 63 | __DEC32_MIN__ 64 | 1E-95DF 65 | __DEC32_SUBNORMAL_MIN__ 66 | 0.000001E-95DF 67 | __DEC64_EPSILON__ 68 | 1E-15DD 69 | __DEC64_MANT_DIG__ 70 | 16 71 | __DEC64_MAX_EXP__ 72 | 385 73 | __DEC64_MAX__ 74 | 9.999999999999999E384DD 75 | __DEC64_MIN_EXP__ 76 | (-382) 77 | __DEC64_MIN__ 78 | 1E-383DD 79 | __DEC64_SUBNORMAL_MIN__ 80 | 0.000000000000001E-383DD 81 | __DECIMAL_BID_FORMAT__ 82 | 1 83 | __DECIMAL_DIG__ 84 | 21 85 | __DEC_EVAL_METHOD__ 86 | 2 87 | __DEPRECATED 88 | 1 89 | __ELF__ 90 | 1 91 | __EXCEPTIONS 92 | 1 93 | __FINITE_MATH_ONLY__ 94 | 0 95 | __FLT_DENORM_MIN__ 96 | 1.40129846e-45F 97 | __FLT_DIG__ 98 | 6 99 | __FLT_EPSILON__ 100 | 1.19209290e-7F 101 | __FLT_EVAL_METHOD__ 102 | 2 103 | __FLT_HAS_DENORM__ 104 | 1 105 | __FLT_HAS_INFINITY__ 106 | 1 107 | __FLT_HAS_QUIET_NAN__ 108 | 1 109 | __FLT_MANT_DIG__ 110 | 24 111 | __FLT_MAX_10_EXP__ 112 | 38 113 | __FLT_MAX_EXP__ 114 | 128 115 | __FLT_MAX__ 116 | 3.40282347e+38F 117 | __FLT_MIN_10_EXP__ 118 | (-37) 119 | __FLT_MIN_EXP__ 120 | (-125) 121 | __FLT_MIN__ 122 | 1.17549435e-38F 123 | __FLT_RADIX__ 124 | 2 125 | __GCC_HAVE_DWARF2_CFI_ASM 126 | 1 127 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 128 | 1 129 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 130 | 1 131 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 132 | 1 133 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 134 | 1 135 | __GNUC_GNU_INLINE__ 136 | 1 137 | __GNUC_MINOR__ 138 | 4 139 | __GNUC_PATCHLEVEL__ 140 | 5 141 | __GNUC__ 142 | 4 143 | __GNUG__ 144 | 4 145 | __GXX_ABI_VERSION 146 | 1002 147 | __GXX_RTTI 148 | 1 149 | __GXX_WEAK__ 150 | 1 151 | __INTMAX_MAX__ 152 | 9223372036854775807LL 153 | __INTMAX_TYPE__ 154 | long long int 155 | __INT_MAX__ 156 | 2147483647 157 | __LDBL_DENORM_MIN__ 158 | 3.64519953188247460253e-4951L 159 | __LDBL_DIG__ 160 | 18 161 | __LDBL_EPSILON__ 162 | 1.08420217248550443401e-19L 163 | __LDBL_HAS_DENORM__ 164 | 1 165 | __LDBL_HAS_INFINITY__ 166 | 1 167 | __LDBL_HAS_QUIET_NAN__ 168 | 1 169 | __LDBL_MANT_DIG__ 170 | 64 171 | __LDBL_MAX_10_EXP__ 172 | 4932 173 | __LDBL_MAX_EXP__ 174 | 16384 175 | __LDBL_MAX__ 176 | 1.18973149535723176502e+4932L 177 | __LDBL_MIN_10_EXP__ 178 | (-4931) 179 | __LDBL_MIN_EXP__ 180 | (-16381) 181 | __LDBL_MIN__ 182 | 3.36210314311209350626e-4932L 183 | __LONG_LONG_MAX__ 184 | 9223372036854775807LL 185 | __LONG_MAX__ 186 | 2147483647L 187 | __NO_INLINE__ 188 | 1 189 | __PTRDIFF_TYPE__ 190 | int 191 | __REGISTER_PREFIX__ 192 | 193 | __SCHAR_MAX__ 194 | 127 195 | __SHRT_MAX__ 196 | 32767 197 | __SIZEOF_DOUBLE__ 198 | 8 199 | __SIZEOF_FLOAT__ 200 | 4 201 | __SIZEOF_INT__ 202 | 4 203 | __SIZEOF_LONG_DOUBLE__ 204 | 12 205 | __SIZEOF_LONG_LONG__ 206 | 8 207 | __SIZEOF_LONG__ 208 | 4 209 | __SIZEOF_POINTER__ 210 | 4 211 | __SIZEOF_PTRDIFF_T__ 212 | 4 213 | __SIZEOF_SHORT__ 214 | 2 215 | __SIZEOF_SIZE_T__ 216 | 4 217 | __SIZEOF_WCHAR_T__ 218 | 4 219 | __SIZEOF_WINT_T__ 220 | 4 221 | __SIZE_TYPE__ 222 | unsigned int 223 | __SSP__ 224 | 1 225 | __STDC_HOSTED__ 226 | 1 227 | __STDC__ 228 | 1 229 | __UINTMAX_TYPE__ 230 | long long unsigned int 231 | __USER_LABEL_PREFIX__ 232 | 233 | __VERSION__ 234 | "4.4.5" 235 | __WCHAR_MAX__ 236 | 2147483647 237 | __WCHAR_TYPE__ 238 | int 239 | __WINT_TYPE__ 240 | unsigned int 241 | __cplusplus 242 | 1 243 | __gnu_linux__ 244 | 1 245 | __i386 246 | 1 247 | __i386__ 248 | 1 249 | __i686 250 | 1 251 | __i686__ 252 | 1 253 | __linux 254 | 1 255 | __linux__ 256 | 1 257 | __pentiumpro 258 | 1 259 | __pentiumpro__ 260 | 1 261 | __unix 262 | 1 263 | __unix__ 264 | 1 265 | i386 266 | 1 267 | linux 268 | 1 269 | unix 270 | 1 271 | -------------------------------------------------------------------------------- /dummy_test/gMacros.dat: -------------------------------------------------------------------------------- 1 | _FORTIFY_SOURCE 2 | 2 3 | _GNU_SOURCE 4 | 1 5 | __BIGGEST_ALIGNMENT__ 6 | 16 7 | __CHAR16_TYPE__ 8 | short unsigned int 9 | __CHAR32_TYPE__ 10 | unsigned int 11 | __CHAR_BIT__ 12 | 8 13 | __DBL_DENORM_MIN__ 14 | 4.9406564584124654e-324 15 | __DBL_DIG__ 16 | 15 17 | __DBL_EPSILON__ 18 | 2.2204460492503131e-16 19 | __DBL_HAS_DENORM__ 20 | 1 21 | __DBL_HAS_INFINITY__ 22 | 1 23 | __DBL_HAS_QUIET_NAN__ 24 | 1 25 | __DBL_MANT_DIG__ 26 | 53 27 | __DBL_MAX_10_EXP__ 28 | 308 29 | __DBL_MAX_EXP__ 30 | 1024 31 | __DBL_MAX__ 32 | 1.7976931348623157e+308 33 | __DBL_MIN_10_EXP__ 34 | (-307) 35 | __DBL_MIN_EXP__ 36 | (-1021) 37 | __DBL_MIN__ 38 | 2.2250738585072014e-308 39 | __DEC128_EPSILON__ 40 | 1E-33DL 41 | __DEC128_MANT_DIG__ 42 | 34 43 | __DEC128_MAX_EXP__ 44 | 6145 45 | __DEC128_MAX__ 46 | 9.999999999999999999999999999999999E6144DL 47 | __DEC128_MIN_EXP__ 48 | (-6142) 49 | __DEC128_MIN__ 50 | 1E-6143DL 51 | __DEC128_SUBNORMAL_MIN__ 52 | 0.000000000000000000000000000000001E-6143DL 53 | __DEC32_EPSILON__ 54 | 1E-6DF 55 | __DEC32_MANT_DIG__ 56 | 7 57 | __DEC32_MAX_EXP__ 58 | 97 59 | __DEC32_MAX__ 60 | 9.999999E96DF 61 | __DEC32_MIN_EXP__ 62 | (-94) 63 | __DEC32_MIN__ 64 | 1E-95DF 65 | __DEC32_SUBNORMAL_MIN__ 66 | 0.000001E-95DF 67 | __DEC64_EPSILON__ 68 | 1E-15DD 69 | __DEC64_MANT_DIG__ 70 | 16 71 | __DEC64_MAX_EXP__ 72 | 385 73 | __DEC64_MAX__ 74 | 9.999999999999999E384DD 75 | __DEC64_MIN_EXP__ 76 | (-382) 77 | __DEC64_MIN__ 78 | 1E-383DD 79 | __DEC64_SUBNORMAL_MIN__ 80 | 0.000000000000001E-383DD 81 | __DECIMAL_BID_FORMAT__ 82 | 1 83 | __DECIMAL_DIG__ 84 | 21 85 | __DEC_EVAL_METHOD__ 86 | 2 87 | __DEPRECATED 88 | 1 89 | __ELF__ 90 | 1 91 | __EXCEPTIONS 92 | 1 93 | __FINITE_MATH_ONLY__ 94 | 0 95 | __FLT_DENORM_MIN__ 96 | 1.40129846e-45F 97 | __FLT_DIG__ 98 | 6 99 | __FLT_EPSILON__ 100 | 1.19209290e-7F 101 | __FLT_EVAL_METHOD__ 102 | 2 103 | __FLT_HAS_DENORM__ 104 | 1 105 | __FLT_HAS_INFINITY__ 106 | 1 107 | __FLT_HAS_QUIET_NAN__ 108 | 1 109 | __FLT_MANT_DIG__ 110 | 24 111 | __FLT_MAX_10_EXP__ 112 | 38 113 | __FLT_MAX_EXP__ 114 | 128 115 | __FLT_MAX__ 116 | 3.40282347e+38F 117 | __FLT_MIN_10_EXP__ 118 | (-37) 119 | __FLT_MIN_EXP__ 120 | (-125) 121 | __FLT_MIN__ 122 | 1.17549435e-38F 123 | __FLT_RADIX__ 124 | 2 125 | __GCC_HAVE_DWARF2_CFI_ASM 126 | 1 127 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 128 | 1 129 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 130 | 1 131 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 132 | 1 133 | __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 134 | 1 135 | __GNUC_GNU_INLINE__ 136 | 1 137 | __GNUC_MINOR__ 138 | 4 139 | __GNUC_PATCHLEVEL__ 140 | 5 141 | __GNUC__ 142 | 4 143 | __GNUG__ 144 | 4 145 | __GXX_ABI_VERSION 146 | 1002 147 | __GXX_RTTI 148 | 1 149 | __GXX_WEAK__ 150 | 1 151 | __INTMAX_MAX__ 152 | 9223372036854775807LL 153 | __INTMAX_TYPE__ 154 | long long int 155 | __INT_MAX__ 156 | 2147483647 157 | __LDBL_DENORM_MIN__ 158 | 3.64519953188247460253e-4951L 159 | __LDBL_DIG__ 160 | 18 161 | __LDBL_EPSILON__ 162 | 1.08420217248550443401e-19L 163 | __LDBL_HAS_DENORM__ 164 | 1 165 | __LDBL_HAS_INFINITY__ 166 | 1 167 | __LDBL_HAS_QUIET_NAN__ 168 | 1 169 | __LDBL_MANT_DIG__ 170 | 64 171 | __LDBL_MAX_10_EXP__ 172 | 4932 173 | __LDBL_MAX_EXP__ 174 | 16384 175 | __LDBL_MAX__ 176 | 1.18973149535723176502e+4932L 177 | __LDBL_MIN_10_EXP__ 178 | (-4931) 179 | __LDBL_MIN_EXP__ 180 | (-16381) 181 | __LDBL_MIN__ 182 | 3.36210314311209350626e-4932L 183 | __LONG_LONG_MAX__ 184 | 9223372036854775807LL 185 | __LONG_MAX__ 186 | 2147483647L 187 | __NO_INLINE__ 188 | 1 189 | __PTRDIFF_TYPE__ 190 | int 191 | __REGISTER_PREFIX__ 192 | 193 | __SCHAR_MAX__ 194 | 127 195 | __SHRT_MAX__ 196 | 32767 197 | __SIZEOF_DOUBLE__ 198 | 8 199 | __SIZEOF_FLOAT__ 200 | 4 201 | __SIZEOF_INT__ 202 | 4 203 | __SIZEOF_LONG_DOUBLE__ 204 | 12 205 | __SIZEOF_LONG_LONG__ 206 | 8 207 | __SIZEOF_LONG__ 208 | 4 209 | __SIZEOF_POINTER__ 210 | 4 211 | __SIZEOF_PTRDIFF_T__ 212 | 4 213 | __SIZEOF_SHORT__ 214 | 2 215 | __SIZEOF_SIZE_T__ 216 | 4 217 | __SIZEOF_WCHAR_T__ 218 | 4 219 | __SIZEOF_WINT_T__ 220 | 4 221 | __SIZE_TYPE__ 222 | unsigned int 223 | __SSP__ 224 | 1 225 | __STDC_HOSTED__ 226 | 1 227 | __STDC__ 228 | 1 229 | __UINTMAX_TYPE__ 230 | long long unsigned int 231 | __USER_LABEL_PREFIX__ 232 | 233 | __VERSION__ 234 | "4.4.5" 235 | __WCHAR_MAX__ 236 | 2147483647 237 | __WCHAR_TYPE__ 238 | int 239 | __WINT_TYPE__ 240 | unsigned int 241 | __cplusplus 242 | 1 243 | __gnu_linux__ 244 | 1 245 | __i386 246 | 1 247 | __i386__ 248 | 1 249 | __i686 250 | 1 251 | __i686__ 252 | 1 253 | __linux 254 | 1 255 | __linux__ 256 | 1 257 | __pentiumpro 258 | 1 259 | __pentiumpro__ 260 | 1 261 | __unix 262 | 1 263 | __unix__ 264 | 1 265 | i386 266 | 1 267 | linux 268 | 1 269 | unix 270 | 1 271 | -------------------------------------------------------------------------------- /test/testVariadicMacros.cpp: -------------------------------------------------------------------------------- 1 | ///All the following example cases of macro usage were given by Yuriy 2 | 3 | 4 | /// Helper macro for the following one to resolve macros inside its arguments 5 | 6 | //#define _XTL_STRING_LITERAL(x) #x 7 | 8 | /// Macro to stringize some expression. 9 | 10 | //#define XTL_STRING_LITERAL(x) _XTL_STRING_LITERAL(x) 11 | 12 | 13 | 14 | /// Somehow operator ## == (or any other) results in error in GCC, so we use 15 | 16 | /// a trick to let users build operator name when they need. 17 | 18 | //#define XTL_IDENTITY(A) A 19 | 20 | //#define XTL_CONCATENATE(A,B) XTL_IDENTITY(A)XTL_IDENTITY(B) 21 | 22 | 23 | 24 | ///Function-like variadic macro: 25 | 26 | /// Macros to use compiler's branch hinting. 27 | 28 | /// \note These macros are only to be used in Case macro expansion, not in 29 | 30 | /// user's code since they explicitly expect a pointer argument 31 | 32 | /// \note We use ... (__VA_ARGS__ parameters) to allow expressions 33 | 34 | /// containing comma as argument. Essentially this is a one arg macro 35 | 36 | //#define XTL_LIKELY(...) (__builtin_expect((long int)(__VA_ARGS__), 1)) 37 | 38 | //#define XTL_UNLIKELY(...) (__builtin_expect((long int)(__VA_ARGS__), 0)) 39 | 40 | 41 | 42 | ///A macro to apply another one to variadic arguments (note variadic arguments have to 43 | ///be in () here, e.g. (__VA_ARGS__): 44 | 45 | 46 | 47 | /// MS Visual C++ 2005 (in which variadic macros became supported) till at 48 | 49 | /// least MS Visual C++ 2010 has a bug in passing __VA_ARGS__ to subsequent 50 | 51 | /// macros as a single token, which results in: 52 | 53 | /// warning C4003: not enough actual parameters for macro 'XTL_ARG_N' 54 | 55 | /// and incorrect behavior. The workaround used here is described at: 56 | 57 | /// https://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement 58 | 59 | //#define XTL_APPLY_VARIADIC_MACRO(macro,tuple) macro tuple 60 | 61 | 62 | 63 | /// A macro used to count a number of variadic arguments. 64 | 65 | /// \note Using this macro without arguments violates 6.10.3p4 of ISO C99 66 | 67 | /// and thus it cannot be used to detect zero arguments. 68 | 69 | /// \note This macro was invented by Laurent Deniau and can be found here: 70 | 71 | /// \see http://groups.google.com/group/comp.std.c/browse_thread/thread/77ee8c8f92e4a3fb/346fc464319b1ee5 72 | 73 | //#define XTL_NARG(...) XTL_APPLY_VARIADIC_MACRO(XTL_NARG_,(__VA_ARGS__,XTL_RSEQ_N())) 74 | 75 | //#define XTL_NARG_(...) XTL_APPLY_VARIADIC_MACRO(XTL_ARG_N,(__VA_ARGS__)) 76 | 77 | 78 | 79 | /// The same as above but assumes a dummy first argument that is not counted 80 | 81 | /// in order to deal with the fact that regular @XTL_NARG cannot cope with 82 | 83 | /// zero arguments. 84 | 85 | /// \note We need here 0 to be a real 0 and not something that evaluates to 0 86 | 87 | /// as is done in some solutions to this problem of NARG, because we 88 | 89 | /// append this number to a name to form another macro! 90 | 91 | //#define XTL_NARG_EX(...) XTL_APPLY_VARIADIC_MACRO(XTL_NARG_EX_,(__VA_ARGS__,XTL_RSEQ_N())) 92 | 93 | //#define XTL_NARG_EX_(...) XTL_APPLY_VARIADIC_MACRO(XTL_ARG_N_EX,(__VA_ARGS__)) 94 | 95 | 96 | 97 | /// Separating a single type parameter among multiple in variadic arguments: 98 | 99 | 100 | 101 | //template struct get_first_param; 102 | 103 | //template struct get_first_param { typedef P1 type; }; 104 | 105 | 106 | 107 | /// This is a helper macro to be able to pass template instantiations as an 108 | 109 | /// argument of a macro. The actual problem is that template instantiations 110 | 111 | /// may contain commas in their argument list, which are treated as macro 112 | 113 | /// argument separator by the preprocessor. Enclosing such type argument in 114 | 115 | /// () directly will not work because (Type) is a conversion expression in C 116 | 117 | /// and compiler reports an error when we try to user (Type) instead of a Type. 118 | 119 | /// \example 120 | 121 | /// Case(TypeArg(MyMap),x,y,z) ... 122 | 123 | /// The solution used here is based on the following discussion: 124 | 125 | /// \see http://stackoverflow.com/questions/4295890/trouble-with-template-parameters-used-in-macros 126 | 127 | //#define TypeArg_(X) get_first_param::type 128 | 129 | //#define TypeArg(...) TypeArg_((__VA_ARGS__)) 130 | 131 | /// Same as @TypeArg but to be used in the template context 132 | 133 | //#define TTypeArg_(X) typename get_first_param::type 134 | 135 | //#define TTypeArg(...) TTypeArg_((__VA_ARGS__)) 136 | 137 | 138 | template 139 | struct AClass {}; 140 | 141 | #define specialize_AClass(...)\ 142 | template<> struct AClass< __VA_ARGS__ > { __VA_ARGS__ a; }; 143 | 144 | specialize_AClass(int) //ok 145 | 146 | specialize_AClass(std::vector >) //error 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(demacrofier) 3 | 4 | ############################################################################### 5 | SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) 6 | SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 7 | SET(HEADER_OUTPUT_PATH ${PROJECT_BINARY_DIR}/include) 8 | 9 | SET(CFE_PREFIX_PATH "/home/hiraditya/work/llvm/install") 10 | 11 | SET(UTILITIES_PREFIX_PATH ".") 12 | 13 | INCLUDE_DIRECTORIES("${UTILITIES_PREFIX_PATH}/general_utilities") 14 | INCLUDE_DIRECTORIES("${CFE_PREFIX_PATH}/include") 15 | ############################################################################### 16 | #THIS HAS TO BE ADDED BEFORE SUPPLYING THE COMPILER FLAGS FOR THIS DIRECTORY FILES 17 | #THE CLANG LIBRARIES COMPILE WITH THE -fno-rtti FLAGS 18 | #AFTER THE LIBRARY HAS BEEN BUILT WE NEED TO SET THE COMPILER FLAGS ONCE AGAIN 19 | #BECAUSE THE BOOST LIBRARIES USE rtti 20 | ADD_SUBDIRECTORY(ClangInterface) 21 | 22 | ############################################################################### 23 | # Compiler options 24 | SET(LLVM_CXXFLAGS "-fPIC -fvisibility-inlines-hidden") 25 | IF(CMAKE_COMPILER_IS_GNUCXX) 26 | SET(CMAKE_CXX_FLAGS "-pedantic -Wall -std=c++11 -g ${LLVM_CXXFLAGS}") 27 | MESSAGE(STATUS "GCC detected - Adding compiler flags ${CMAKE_CXX_FLAGS}") 28 | ELSEIF(MSVC) 29 | MESSAGE(STATUS "MSVC detected - Adding compiler flags") 30 | ENDIF(CMAKE_COMPILER_IS_GNUCXX) 31 | 32 | ############################################################################### 33 | #INCLUDE OTHER SUBDIRECTORIES HERE WHICH ARE FINE WITH -fno-rtti. 34 | ADD_SUBDIRECTORY(general_utilities) 35 | 36 | ############################################################################### 37 | INCLUDE_DIRECTORIES("${UTILITIES_PREFIX_PATH}/general_utilities") 38 | INCLUDE_DIRECTORIES("${CFE_PREFIX_PATH}/include") 39 | 40 | ############## INCLUDE DIRECTORIES RELATED TO CLANG ########################### 41 | INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}") 42 | INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/ClangInterface") 43 | 44 | ############################ DEBUG MACROS ##################################### 45 | #ADD_DEFINITIONS(-DBUILD_NEW_MACRO_LIST) 46 | ADD_DEFINITIONS(-DCLANG_AST_DEBUG_PRINT) 47 | #ADD_DEFINITIONS(-DDEBUG_PARSER_PRINT) 48 | #ADD_DEFINITIONS(-DDEBUG_CONDITIONALS_PRINT) 49 | #ADD_DEFINITIONS(-DDEBUG_CONDITIONALS1_PRINT) 50 | #ADD_DEFINITIONS(-DDEBUG_DEMACROFIER_PRINT) 51 | #ADD_DEFINITIONS(-DDEBUG_RLPARSER_PRINT) 52 | #ADD_DEFINITIONS(-DDEBUG_RLPARSER2_PRINT) 53 | #ADD_DEFINITIONS(-DDEBUG_TREE_PRINT) 54 | #ADD_DEFINITIONS(-DBUILD_NEW_MACRO_LIST_PRINT) 55 | #ADD_DEFINITIONS(-DDEBUG_MACRO_DEPENDENCY_PRINT) 56 | #ADD_DEFINITIONS(-DDEBUG_MACRO_DEPENDENCY2_PRINT) 57 | #ADD_DEFINITIONS(-DENABLE_WARNING_PRINT) 58 | #ADD_DEFINITIONS(-DDEBUG_MACRO_CLASS_PRINT) 59 | #ADD_DEFINITIONS(-DDEBUG_MACRO_CLASS2_PRINT) 60 | #ADD_DEFINITIONS(-DDEBUG_MACRO_USE_CASE_PRINT) 61 | #ADD_DEFINITIONS(-DDEBUG_CLEANUP_CODE_PRINT) 62 | #ADD_DEFINITIONS(-DDEBUG_VALIDATOR_PRINT) 63 | ADD_DEFINITIONS(-DDEBUG_SUGGESTION_PRINT) 64 | #ADD_DEFINITIONS(-DGMACROS="${HEADER_OUTPUT_PATH}/gMacros.dat") 65 | 66 | ############## DEFINITIONS RELATED TO CLANG ################################### 67 | ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS) 68 | ADD_DEFINITIONS(-D__STDC_FORMAT_MACROS) 69 | ADD_DEFINITIONS(-D__STDC_LIMIT_MACROS) 70 | ADD_DEFINITIONS(-D_GNU_SOURCE) 71 | ############################################################################### 72 | ADD_LIBRARY(cpp2cxx-core SHARED 73 | RlCategory.cpp 74 | ReplacementList.cpp 75 | RlParser.cpp 76 | Macro.cpp 77 | MacroStat.cpp 78 | UseCaseState.cpp 79 | DepGraph.cpp 80 | CondParser.cpp 81 | Demacrofier.cpp 82 | Parser.cpp 83 | FileManager.cpp 84 | Overseer.cpp 85 | ConfigScheme.cpp 86 | ) 87 | 88 | #################### SPECIFYING THE LINK DIRECTORIES ########################## 89 | # Library directory paths 90 | LINK_DIRECTORIES( 91 | "/usr/lib" 92 | "/usr/local/lib" 93 | "${CMAKE_PREFIX_PATH}/lib" 94 | "${CFE_PREFIX_PATH}/lib" 95 | ) 96 | 97 | ############################################################################### 98 | ADD_EXECUTABLE(cpp2cxx-suggest 99 | MainSuggest.cpp 100 | ) 101 | 102 | ADD_EXECUTABLE(cpp2cxx-finalize 103 | MainFinalize.cpp 104 | ) 105 | FILE(COPY "cpp2cxx-validate.py" DESTINATION ${EXECUTABLE_OUTPUT_PATH}) 106 | FILE(COPY "gMacros.dat" DESTINATION ${HEADER_OUTPUT_PATH}) 107 | ############################################################################### 108 | #ADD_LIBRARY() 109 | #FIND_LIBRARY() 110 | TARGET_LINK_LIBRARIES(cpp2cxx-suggest cpp2cxx-core boost_system boost_wave 111 | boost_program_options ASTConsumer cpp2cxx-debug clang 112 | ) 113 | 114 | TARGET_LINK_LIBRARIES(cpp2cxx-finalize cpp2cxx-core boost_system boost_wave 115 | boost_program_options ASTConsumer cpp2cxx-debug clang 116 | ) 117 | -------------------------------------------------------------------------------- /RlCategory.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef RL_CATEGORY_H 24 | #define RL_CATEGORY_H 25 | 26 | /** 27 | * @file RlCategory.h 28 | * @brief contains various enum classes which are helpful in classifying the 29 | * replacement list of macro, it also contains replacement_list_token_type 30 | * which gives information about what all different types of tokens 31 | * the replacement list has. 32 | * @version 1.0 33 | * @author Aditya Kumar 34 | * @note 35 | * compiles with g++-4.5 or higher, 36 | * for compiling pass -std=c++0x to the compiler 37 | */ 38 | #include 39 | /** 40 | * @class ReplacementListDependencyCategory 41 | * @brief To tell whether the replacement list of the macro is independent of 42 | * the identifiers previously defined 43 | */ 44 | enum class ReplacementListDependencyCategory 45 | { 46 | /// having any identifier previously defined 47 | dependent, 48 | /// no identifiers only constants 49 | independent 50 | }; 51 | 52 | /** 53 | * @class ReplacementListClosureCategory 54 | * @brief To tell whether the replacement list of macro is a closed/complete expression 55 | */ 56 | enum class ReplacementListClosureCategory 57 | { 58 | /// incomplete expressions 59 | open, 60 | /// complete expressions in the sense of C++ expressions without the semicolon 61 | closed 62 | }; 63 | 64 | /** 65 | * @struct ReplacementListTokenType 66 | * @brief token types present in the Replacement list 67 | */ 68 | struct ReplacementListTokenType 69 | { 70 | ReplacementListTokenType() 71 | { 72 | Reset(); 73 | } 74 | 75 | void Reset() 76 | { 77 | identifier_type = false; 78 | /// string numeric etc. 79 | literal_type = false; 80 | /// unary operators like !, ~ , unary plus, unary minus 81 | unary_operator_type = false; 82 | /// all binary operators except concatenation and stringification 83 | binary_operator_type = false; 84 | /// ? : conditional operator 85 | ternary_operator_type = false; 86 | /// > , < , == , != etc 87 | relational_operator_type = false; 88 | /// +=, -= , = , etc 89 | assignment_type = false; 90 | /// () 91 | paren_type = false; 92 | /// {} 93 | braces_type = false; 94 | /// all c++ keywords 95 | keyword_type = false; 96 | /// reject_type 97 | reject_type = false; 98 | /// all others which cannot be categorised 99 | special_type = false; 100 | /// when the replacement text has a statement, i.e. semicolon at the end 101 | statement_type = false; 102 | /// unknown tokens 103 | unknown_type = false; 104 | /// when atleast one of the tokens is dependent on another macro 105 | /// and the dependency is out of topological order 106 | out_of_order_dependent_type = false; 107 | } 108 | /// expression_type when there are more than two tokens 109 | /// identifiers 110 | bool identifier_type; 111 | /// string numeric etc. 112 | bool literal_type; 113 | /// unary operators like !, ~ , unary plus, unary minus 114 | bool unary_operator_type; 115 | /// all binary operators except concatenation and stringification 116 | bool binary_operator_type; 117 | /// ? : conditional operator 118 | bool ternary_operator_type; 119 | /// > , < , == , != etc 120 | bool relational_operator_type; 121 | /// +=, -= , = , etc 122 | bool assignment_type; 123 | /// () 124 | bool paren_type; 125 | /// {} 126 | bool braces_type; 127 | /// all c++ keywords 128 | bool keyword_type; 129 | /// e.g. __FILE__ and __LINE__ 130 | bool reject_type; 131 | /// when the replacement text has a statement, i.e. semicolon at the end 132 | bool statement_type; 133 | /// all others which cannot be categorised 134 | bool special_type; 135 | /// unknown tokens 136 | bool unknown_type; 137 | /// when atleast one of the tokens is dependent on another macro 138 | /// and the dependency is out of topological order 139 | bool out_of_order_dependent_type; 140 | }; 141 | 142 | /** 143 | * @typedef ReplacementListDependencyCategory RlDCat 144 | */ 145 | typedef ReplacementListDependencyCategory RlDCat; 146 | /** 147 | * @typedef ReplacementListClosureCategory RlCCat; 148 | */ 149 | typedef ReplacementListClosureCategory RlCCat; 150 | /** 151 | * @typedef ReplacementListTokenType RlTokType; 152 | */ 153 | typedef ReplacementListTokenType RlTokType; 154 | std::ostream& operator<<(std::ostream& os,RlCCat const& cat); 155 | std::ostream& operator<<(std::ostream& os,RlDCat const& cat); 156 | 157 | #endif /*RL_CATEGORY_H*/ 158 | -------------------------------------------------------------------------------- /Demacrofier.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef DEMACROFIER 24 | #define DEMACROFIER 25 | 26 | 27 | /** 28 | * @file Demacrofier.h 29 | * @brief demacrofies the macros and returns the demacrofied PPMacro as a string 30 | * @version 1.0 31 | * @author Aditya Kumar 32 | * @details 33 | * compiles with g++-4.5 or higher, 34 | * for compiling pass -std=c++0x to the compiler 35 | */ 36 | 37 | #include "Macro.h" 38 | #include "FunctionInfo.h" 39 | #include "ValidatorMap.h" 40 | 41 | #include 42 | 43 | /** 44 | * @class Parser 45 | * @brief forward declaration 46 | */ 47 | class Parser; 48 | 49 | /** 50 | * @class Demacrofier 51 | * @brief demacrofies the macro on a per macro basis 52 | */ 53 | class Demacrofier { 54 | public: 55 | Demacrofier(); 56 | /// @todo change pointer to const ref 57 | /// when cleaning up, the translations are put without any conditionals 58 | /// The \e Translate function will generate the demacrofication without 59 | /// any conditionals wrapped around it. The code generated will have 60 | /// several formatting modifications as compared to the original code. 61 | 62 | /// when cleanup = false, translations are put with #ifdef conditionals 63 | /// and by default they are disabled; the macros are enabled. 64 | std::string Translate(PPMacro const* m_ptr, std::ostream& stat, bool cleanup, bool demacrofy); 65 | 66 | void SetMacroInvocationStat(InvocationStat_t* pInvocationStat); 67 | void SetASTStat(ASTMacroStat_t* pASTMacroStat); 68 | void SetValidator(ValidMacros_t const* v_macros); 69 | private: 70 | 71 | /** 72 | * #define FXY(X,Y,Z) ((X) + (Y)) 73 | * template 74 | * auto FXY(T1 X, T2 Y, T3 Z) -> decltype(((X) + (Y))) 75 | * { 76 | * return ((X) + (Y)); 77 | * } 78 | */ 79 | std::string DemacrofyFunctionLike(PPMacro const* m_ptr) const; 80 | /** 81 | * #define FXY(X,Y,Z) ((X) + (Y)) 82 | * auto FXY = [](decltype(i) X, decltype(j) Y, decltype(k) Z) 83 | * { return ((X)+(Y)); } 84 | * int i = FXY(i,j,k); 85 | * @todo if type can be deduced from clang then do it 86 | * for statement like macros use void function 87 | */ 88 | // lambda function transformation 89 | std::string DemacrofyFunctionLikePostponed(const PPMacro * m_ptr)const; 90 | std::string GetFunctionClosure(const PPMacro *m_ptr)const; 91 | std::string GetFunctionArgs(const PPMacro *m_ptr)const; 92 | std::string GetFunctionBody(const PPMacro *m_ptr)const; 93 | /** 94 | * #define shift2 var = var<<2 95 | * auto shift2 = [&var]()->void { var = var<<2; } 96 | */ 97 | std::string DemacrofyObjectLikePostponed(const PPMacro *m_ptr) const; 98 | /** 99 | * #define _abc 1000 100 | * constexpr auto _abc = 1000; 101 | */ 102 | std::string DemacrofyObjectLike(PPMacro const* m_ptr) const; 103 | /** 104 | * #define proc(X,Y) { FXY(X,Y,0); } 105 | * template 106 | * void proc(T1 X, T2 Y) 107 | * { 108 | * FXY(X,Y,0); 109 | * } 110 | */ 111 | std::string DemacrofyMultipleStatements(PPMacro const* m_ptr) const; 112 | std::string DemacrofyStatementType(PPMacro const* m_ptr) const; 113 | bool IsDemacrofiable(PPMacro const& mac) const; 114 | 115 | std::string SuggestTranslation(std::string const& unique_macro_switch, 116 | std::string const& demacrofied_fstream, 117 | std::string const& original_str) const; 118 | 119 | std::string GenerateTranslation(std::string const& macro_iden, 120 | std::string const& unique_macro_switch, 121 | std::string const& demacrofied_fstream) const; 122 | 123 | std::string GenerateUniqueMacroSwitch(PPMacro const* m_ptr) const; 124 | 125 | void InsertToReadyQueue(std::stringstream const& macro_iden, 126 | std::string const& outstr); 127 | 128 | bool CollectDemacrofiedString(PPMacro const* m_ptr, std::string& demacrofied_str) const; 129 | 130 | private: 131 | 132 | // it can change the readyQueue 133 | friend class Parser; 134 | 135 | // keeps a list of postponed macros according to the line number 136 | typedef std::map ReadyQueue_t; 137 | 138 | ReadyQueue_t readyQueue; 139 | // contains all the line numbers where macros were invoked in current file 140 | InvocationStat_t* pInvocationStat; 141 | // containes all the information about macros in current file a/c clang 142 | ASTMacroStat_t* pASTMacroStat; 143 | 144 | //pointer to the container having all the valid macros 145 | //to be used only when the cleanup is in process 146 | ValidMacros_t const* pValidaMacros; 147 | std::string headerGuard; 148 | int count; 149 | }; 150 | 151 | #endif /*DEMACROFIER*/ 152 | -------------------------------------------------------------------------------- /test/example.cpp: -------------------------------------------------------------------------------- 1 | #define depth0 0 2 | #define shift2 {bit = bit << 2} 3 | #define a 100 4 | #define b 200 5 | #define INTERFACE_IArchiveUpdateCallback(x) \ 6 | INTERFACE_IProgress(x); \ 7 | STDMETHOD(GetUpdateItemInfo)(UInt32 index, \ 8 | Int32 *newData, /*1 - new data, 0 - old data */ \ 9 | Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \ 10 | UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \ 11 | ) x; \ 12 | STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ 13 | STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ 14 | STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ 15 | 16 | #define RB1(i, edx, edi) \ 17 | AS2( mov AS_REG_7d, [Wt_2(i)] )\ 18 | AS2( mov edi, [Wt_15(i)])\ 19 | AS2( mov ebx, AS_REG_7d )\ 20 | AS2( shr AS_REG_7d, 10 )\ 21 | AS2( ror ebx, 17 )\ 22 | AS2( xor AS_REG_7d, ebx )\ 23 | AS2( ror ebx, 2 )\ 24 | AS2( xor ebx, AS_REG_7d )/* s1(W_t-2) */\ 25 | AS2( add ebx, [Wt_7(i)])\ 26 | AS2( mov AS_REG_7d, edi )\ 27 | AS2( shr AS_REG_7d, 3 )\ 28 | AS2( ror edi, 7 )\ 29 | AS2( add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\ 30 | AS2( xor AS_REG_7d, edi )\ 31 | AS2( add edx, [Kt(i)])\ 32 | AS2( ror edi, 11 )\ 33 | AS2( add edx, H(i) )\ 34 | AS2( xor AS_REG_7d, edi )/* s0(W_t-15) */\ 35 | AS2( add AS_REG_7d, ebx )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\ 36 | AS2( mov [Wt(i)], AS_REG_7d)\ 37 | AS2( add edx, AS_REG_7d )\ 38 | 39 | #define the "MacID230984230982304" 40 | #define the "SOmething else" 41 | 42 | #define c 300 43 | #define THIS_FILE __FILE__ 44 | #if +a + (-b+c) 45 | #define depth1 1 + t1 46 | #if !defined(a) || defined(b) && defined(c) 47 | #define depth2 1 + depth1 + a + t1 48 | #ifdef a 49 | #endif 50 | #ifndef __DBL_MIN_EXP__ 51 | #define depth3 1+depth2+c+__SHRT_MAX__ 52 | #endif 53 | #endif 54 | #endif 55 | 56 | #define CRYPTOPP_X86_ASM_AVAILABLE 57 | #define FXY(X,Y,Z) ((X) + (Y)) 58 | #define fun() FXY(1,200,3) 59 | 60 | int i = fun(); 61 | int super(int i,int j) 62 | { 63 | #define INSIDE_FUN_SUPER(X,Y) X+100 + i 64 | 65 | 66 | return INSIDE_FUN_SUPER(10000, 4000); 67 | } 68 | int l = FXY((i+i),super(10,12),100); 69 | 70 | int aPtr[] = {1,2,3,4,5,6,7,8,9,10}; 71 | int cPtr[] = {1,2,3,4,5,6,7,8,9,10}; 72 | 73 | #define _a(i) aPtr[i%9] + _abc // 13 is inverse of 4 mod 17 74 | #define _c(i) cPtr[((i)*13+16) % 7] 75 | #define _b(i, j) b##i[(j)*2%8 + (j)/4] 76 | #define _abc 1000 77 | #define t12 10*256 78 | #define TYPE_CHAR (char *) 79 | #define Ptr(X) X* 80 | 81 | #define proc(X,Y) {\ 82 | FXY(X,Y,0);\ 83 | } 84 | #define MSB(x) (((x) >> 24) & 0xffU) /* most significant byte */ 85 | #define SSB(x) (((x) >> 16) & 0xffU) /* second in significance */ 86 | #define TSB(x) (((x) >> 8) & 0xffU) /* third in significance */ 87 | #define LSB(x) (((x) ) & 0xffU) /* least significant byte */ 88 | 89 | #define squareRound(text, temp, T0, T1, T2, T3, roundkey) \ 90 | { \ 91 | temp[0] = T0[MSB (text[0])] \ 92 | ^ T1[MSB (text[1])] \ 93 | ^ T2[MSB (text[2])] \ 94 | ^ T3[MSB (text[3])] \ 95 | ^ roundkey[0]; \ 96 | temp[1] = T0[SSB (text[0])] \ 97 | ^ T1[SSB (text[1])] \ 98 | ^ T2[SSB (text[2])] \ 99 | ^ T3[SSB (text[3])] \ 100 | ^ roundkey[1]; \ 101 | temp[2] = T0[TSB (text[0])] \ 102 | ^ T1[TSB (text[1])] \ 103 | ^ T2[TSB (text[2])] \ 104 | ^ T3[TSB (text[3])] \ 105 | ^ roundkey[2]; \ 106 | temp[3] = T0[LSB (text[0])] \ 107 | ^ T1[LSB (text[1])] \ 108 | ^ T2[LSB (text[2])] \ 109 | ^ T3[LSB (text[3])] \ 110 | ^ roundkey[3]; \ 111 | } /* squareRound */ 112 | 113 | #define squareFinal(text, temp, S, roundkey) \ 114 | { \ 115 | text[0] = ((word32) (S[MSB (temp[0])]) << 24) \ 116 | ^ ((word32) (S[MSB (temp[1])]) << 16) \ 117 | ^ ((word32) (S[MSB (temp[2])]) << 8) \ 118 | ^ (word32) (S[MSB (temp[3])]) \ 119 | ^ roundkey[0]; \ 120 | text[1] = ((word32) (S[SSB (temp[0])]) << 24) \ 121 | ^ ((word32) (S[SSB (temp[1])]) << 16) \ 122 | ^ ((word32) (S[SSB (temp[2])]) << 8) \ 123 | ^ (word32) (S[SSB (temp[3])]) \ 124 | ^ roundkey[1]; \ 125 | text[2] = ((word32) (S[TSB (temp[0])]) << 24) \ 126 | ^ ((word32) (S[TSB (temp[1])]) << 16) \ 127 | ^ ((word32) (S[TSB (temp[2])]) << 8) \ 128 | ^ (word32) (S[TSB (temp[3])]) \ 129 | ^ roundkey[2]; \ 130 | text[3] = ((word32) (S[LSB (temp[0])]) << 24) \ 131 | ^ ((word32) (S[LSB (temp[1])]) << 16) \ 132 | ^ ((word32) (S[LSB (temp[2])]) << 8) \ 133 | ^ (word32) (S[LSB (temp[3])]) \ 134 | ^ roundkey[3]; \ 135 | } /* squareFinal */ 136 | 137 | #include 138 | 139 | int main() 140 | { 141 | int a1 = a; 142 | int b1 = b; 143 | int c1 = c; 144 | 145 | std::cout<> 3 154 | shift4; 155 | ////// 156 | int temp[4]; 157 | int text[] = {1,2,4,8}; 158 | int t0[] = {1,2,4,8}; 159 | int t1[] = {1,2,4,8}; 160 | int t2[] = {1,2,4,8}; 161 | int t3[] = {10,2,4,8}; 162 | int rk[] = {10,2,4,8}; 163 | squareRound(text,temp,t0,t1,t2,t3,rk); 164 | std::cout< 39 | #include 40 | #include 41 | #include 42 | 43 | //depending upon the demacrofication scheme the demacrofier should 44 | //return to the subject class which should call the FileManager for file handling 45 | /** 46 | * @class FileManagerScheme 47 | * @brief forward declaration 48 | */ 49 | class FileManagerScheme; 50 | 51 | /** 52 | * @class DemacroficationScheme 53 | * @brief forward declaration 54 | */ 55 | class DemacroficationScheme; 56 | 57 | /** 58 | * @class OverSeer 59 | * @brief forward declaration 60 | */ 61 | class Overseer; 62 | 63 | /** 64 | * @class FileManager 65 | * @brief will be responsible for maintaining all the files that are required 66 | * to be demacrofied and 67 | */ 68 | class FileManager { 69 | 70 | public: 71 | /// @function FileManager(FileManagerScheme const& fs) 72 | /// @brief constructor takes the file scheme FileManagerScheme 73 | /// uses the FileManagerScheme to configure the settings 74 | /// configuration can also be changed using the Configure function. 75 | FileManager(FileManagerScheme const& fs, DemacroficationScheme const& ds); 76 | 77 | /// @brief uses the FileManagerScheme to configure the settings 78 | void Configure(FileManagerScheme const& fs); 79 | 80 | /// @brief performs checks etc., not implemented as of now 81 | /// check if the directory exists or not, if the files 82 | /// in the list are actually found or not 83 | bool SanityCheck(); 84 | // 85 | 86 | //not useful as of now 87 | /* 88 | FileManager(std::vector const& input_files, 89 | std::vector const& output_files, 90 | std::string const& input_directory, 91 | std::string const& output_directory, 92 | std::string const& backup_directory); 93 | //not useful as of now 94 | FileManager(std::vector const& input_files, 95 | std::vector const& output_files, 96 | std::string const& backup_directory); 97 | //not useful as of now 98 | FileManager(std::vector const& input_files); 99 | */ 100 | 101 | std::vectorconst& OutputFiles(); 102 | std::vectorconst& InputFiles(); 103 | std::string const& OutputDirectory(); 104 | std::string const& InputDirectory(); 105 | 106 | //check whether this file is there in the list of output_files or not 107 | void UpdateFile(std::string const& file_str); 108 | void UpdateFile(std::ostream& fp, std::string const& file_str); 109 | 110 | /// @brief observer, gets updated whenever a new file is demacrofied 111 | void UpdateFile(Overseer const& overseer); 112 | 113 | /// @brief returns the list of input files 114 | std::vector const& GetInputFiles() const; 115 | 116 | /// @brief returns the output file which will be updated in the 117 | /// current iteration 118 | std::string GetOutputFile(); 119 | 120 | /// @brief returns the search paths 121 | std::vector const& GetSearchPaths() const; 122 | 123 | /// @brief writes the string to the log file fileManagerScheme.pConfigFile 124 | void WriteLog(std::string const& str); 125 | 126 | /// @brief writes the header to the stat file 127 | void PrepareMacroStatFile(); 128 | 129 | /// @brief writes the header to the demacrofied macro stat file 130 | void PrepareDemacrofiedMacroStatFile(); 131 | 132 | /// @brief returns the reference to the pLogFile where the messages 133 | /// can be logged 134 | std::ostream& GetLogFile(); 135 | 136 | /// @brief returns the reference to the pListMacroFile where the macros 137 | /// can be listed 138 | std::ostream& GetMacroStatFile(); 139 | 140 | /// @brief returns the reference to the pDemacrofiedMacroStatFile 141 | /// where the list of macros and related information can be logged 142 | std::ostream& GetDemacrofiedMacroStatFile(); 143 | 144 | private: 145 | /// @var reference to the fileManagerScheme 146 | FileManagerScheme const& fileManagerScheme; 147 | 148 | DemacroficationScheme const& demacroficationScheme; 149 | /// @todo try to make a map from input files to output files 150 | unsigned int inputFileIndex; 151 | unsigned int outputFileIndex; 152 | 153 | }; 154 | 155 | #endif /*FILEMANAGER_H*/ 156 | -------------------------------------------------------------------------------- /Overseer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #include "Overseer.h" 24 | #include "FileManager.h" 25 | #include "Parser.h" 26 | #include "DepGraph.h" 27 | #include "ExceptionHandler.h" 28 | 29 | #include "file_type.hpp" 30 | 31 | Overseer::Overseer(ConfigScheme& config_scheme) 32 | :configScheme(config_scheme) 33 | { 34 | pFileManager = new FileManager(GetFileManagerScheme(), GetDemacroficationScheme()); 35 | pParser = new Parser(GetDemacroficationScheme(),GetLogFile(),GetMacroStatFile()); 36 | } 37 | 38 | void Overseer::ConfigureFileManager() 39 | { 40 | pFileManager->Configure(configScheme.GetFileManagerScheme()); 41 | } 42 | 43 | Overseer::~Overseer() 44 | { 45 | delete pFileManager; 46 | delete pParser; 47 | } 48 | 49 | /** 50 | * @function StartProcessing 51 | * @details processing is to be done in the following steps 52 | * 1. configure file manager 53 | * 2. get one file from file manager 54 | * 3. call the parser 55 | * 4. get the macro count 56 | * 5. run the dependency analyzer,print total order 57 | * 6. call the demacrofier as per the scheme 58 | * 7. update the demacrofied string to the file manager 59 | * 8. call the build class 60 | * 9. goto step2 61 | * 10. catch any errors 62 | */ 63 | 64 | void Overseer::StartProcessing(bool demacrofy) 65 | {/// @todo after demacrofication maintain a list of all the macro 66 | /// identities so that each identifier can be defined in the make file 67 | /// and subsequently compiled 68 | try { 69 | std::vector::const_iterator v_iter; 70 | v_iter = GetInputFiles().begin(); 71 | for( ; v_iter!=GetInputFiles().end(); ++v_iter) { 72 | GenerateExternalASTHandler(*v_iter); 73 | //GetInformationFromExternalSource(*v_iter); 74 | RunParser(*v_iter); 75 | if(demacrofy){ 76 | RunDemacrofier(); 77 | RunDependencyAnalyzer(); 78 | } 79 | } 80 | } catch(ExceptionHandler& e) { 81 | //std::cout<<"There was some error in start processing"; 82 | GetLogFile() << "Error: "< const& Overseer::GetInputFiles() 87 | { 88 | return pFileManager->GetInputFiles(); 89 | } 90 | 91 | void Overseer::RunParser(std::string log_file_name) 92 | { 93 | /// pass the data collected from clang front end 94 | pParser->Parse(log_file_name, &ASTMacroStat); 95 | //pMacTree = pParser->GetMacTree(); 96 | } 97 | 98 | void Overseer::RunDependencyAnalyzer() 99 | { 100 | //pass the tree pointer 101 | //pass the log_file pointer 102 | //pass a call_back function(observer) which will give the 103 | //return the relevant error message to the dependency analyser 104 | //or may be it can only take the relevant error message and put that into 105 | //log file 106 | // 107 | pParser->PPAnalyzeMacroDependency(GetLogFile()); 108 | // 109 | //dependency analyzer should do the analysis and then put the analysis 110 | //result into the log_file 111 | 112 | } 113 | 114 | void Overseer::PrintTotalOrder() 115 | { 116 | //call the dep_analyzer to print the total order 117 | //to the file_pointer passed to the dependency_analyzer 118 | } 119 | 120 | void Overseer::RunDemacrofier() 121 | { 122 | //if(one_file_at_a_time) 123 | //std::string demac_string = demacrofy(tree_ptr,input_file_ptr) 124 | //else if(one_macro_at_a_time) 125 | //std::string demac_string = demacrofy(mac_ptr) 126 | //else invalid option 127 | pParser->Demacrofy(GetStatFile(),configScheme.GetDemacroficationScheme().multipleDefinitions); 128 | UpdateFileManager(); 129 | } 130 | 131 | void Overseer::UpdateFileManager() 132 | { 133 | //std::cout<UpdateFile(*this); 135 | } 136 | 137 | /// @brief called by the FileManager class to update the file 138 | void Overseer::WriteOutputFile(std::ostream& os) const 139 | { 140 | pParser->GetDemacrofiedFile(os); 141 | } 142 | 143 | std::ostream& Overseer::GetLogFile() 144 | { 145 | return pFileManager->GetLogFile(); 146 | } 147 | 148 | std::ostream& Overseer::GetMacroStatFile() 149 | { 150 | return pFileManager->GetMacroStatFile(); 151 | } 152 | 153 | std::ostream& Overseer::GetStatFile() 154 | { 155 | return pFileManager->GetDemacrofiedMacroStatFile(); 156 | } 157 | 158 | DemacroficationScheme& Overseer::GetDemacroficationScheme() 159 | { 160 | return configScheme.GetDemacroficationScheme(); 161 | } 162 | 163 | FileManagerScheme& Overseer::GetFileManagerScheme() 164 | { 165 | return configScheme.GetFileManagerScheme(); 166 | } 167 | 168 | void Overseer::GenerateExternalASTHandler(const std::string& filename) 169 | { 170 | /// generally the function definitions are not in header files. This has been done to make things faster and minimize 171 | /// clang errors. As there are cases where header files are not self contained e.g. poco-1.4.3p1/XML$ vi src/xmlrole.h 172 | /// 173 | if(general_utilities::header_file(filename)) 174 | return; 175 | clang::CompilerInstance ci; 176 | //InvocationStat_t inv_stat; 177 | pASTConsumer = new MyASTConsumer; 178 | MyASTConsumer& ASTConsumer = *pASTConsumer; 179 | 180 | ASTConsumer.InitializeCI(ci, pFileManager->GetSearchPaths()); 181 | 182 | ASTConsumer.DumpContent(filename); 183 | 184 | //ASTConsumer.PrintStats(); 185 | ASTConsumer.VerifyMacroScope(true); 186 | ASTMacroStat = ASTConsumer.GetMacroStat(); 187 | //inv_stat = ASTConsumer.GetInvocationStat(); 188 | } 189 | 190 | /* 191 | void Overseer::GenerateExternalASTHandler() 192 | { 193 | clang::CompilerInstance *pci = new clang::CompilerInstance; 194 | pASTConsumer = new MyASTConsumer; 195 | pASTConsumer->Initialize(*pci); 196 | } 197 | 198 | void Overseer::GetInformationFromExternalSource(const std::string& filename) 199 | { 200 | pASTConsumer->DumpContent(filename); 201 | pASTConsumer->PrintStats(); 202 | pASTConsumer->VerifyMacroScope(); 203 | delete pASTConsumer; 204 | pASTConsumer = NULL; 205 | } 206 | */ 207 | -------------------------------------------------------------------------------- /Macro.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef MACRO_HPP 24 | #define MACRO_HPP 25 | #include "MacroScopeClassifier.h" 26 | #include "ReplacementList.h" 27 | #include "RlCategory.h" 28 | 29 | #include "DemacBoostWaveIncludes.h" 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | // (c) Copyright 37 | // ALL RIGHTS RESERVED 38 | /** 39 | * @file Macro.h 40 | * @brief contains the PPMacro class and various enum classes useful 41 | * for classification of macros into different categories. 42 | * @version 1.0 43 | * @author Aditya Kumar 44 | * @details 45 | * compiles with g++-4.5 or higher, 46 | * for compiling pass -std=c++0x to the compiler 47 | */ 48 | 49 | 50 | 51 | /** forward declaration 52 | * @class DemacroficationScheme 53 | */ 54 | struct DemacroficationScheme; 55 | 56 | /** forward declaration 57 | * @class RlParser 58 | */ 59 | class RlParser; 60 | 61 | /** forward declaration 62 | * @class MacroStat 63 | */ 64 | class MacroStat; 65 | 66 | /** 67 | * @class PPMacro 68 | * The class to keep all the details of a macro 69 | */ 70 | class PPMacro 71 | { 72 | public: 73 | PPMacro(std::ostream& log_file); 74 | ~PPMacro(); 75 | void set_identifier(token_type const& tok); 76 | void put_tokens(std::vector const& vec_tokens); 77 | void set_identifier_parameters(token_type const& tok, 78 | unsigned int parameter_count); 79 | void set_identifier_str(std::string str); 80 | void set_replacement_list(token_type tok); 81 | void set_replacement_list_str(std::string str, RlParser & rl_parser); 82 | void set_operation(PPOperation op); 83 | void set_macro_category(MacroCategory m_cat); 84 | void set_replacement_list_category(RlParser & rl_parser); 85 | void set_conditional_category(CondCategory condCat); 86 | void set_macro_scope_category(MacroScopeCategory m_scat); 87 | //for the object like macro first == last for the use_case 88 | // keep only the first use case 89 | // as a complete list of use case is already returned by clang 90 | void set_use_case(std::pair& token_iter_range); 91 | void set_use_case_string(std::vector& vec_string); 92 | 93 | token_type const get_identifier() const; 94 | std::vector const& get_tokens() const; 95 | int get_num_tokens() const; 96 | std::string const& get_identifier_str() const; 97 | void dump() const; 98 | std::string get_replacement_list_str() const; 99 | std::string const& get_formatted_replacement_list_str() const; 100 | std::string const& get_replacement_list_str_with_comments() const; 101 | std::vector > const& 102 | get_identifier_parameters() const; 103 | 104 | ReplacementList& get_replacement_list(); 105 | ReplacementList const& get_replacement_list() const; 106 | PPOperation get_operation() const; 107 | MacroCategory get_macro_category() const; 108 | 109 | bool is_function_like() const 110 | { return m_cat == MacroCategory::function_like; } 111 | 112 | bool is_object_like() const 113 | { return m_cat == MacroCategory::object_like; } 114 | 115 | RlDCat 116 | get_replacement_list_dependency_category() const; 117 | 118 | RlCCat 119 | get_replacement_list_closure_category() const; 120 | 121 | std::list 122 | get_replacement_list_idlist() const; 123 | 124 | std::list 125 | get_replacement_list_dep_idlist() const; 126 | 127 | CondCategory get_conditional_category() const; 128 | 129 | std::pair 130 | get_use_case() const; 131 | 132 | std::vector const& 133 | get_use_case_string() const; 134 | 135 | MacroScopeCategory get_macro_scope_category() const; 136 | 137 | bool IsEquivalent(std::pair token_iter_range) const; 138 | void AnalyzeIdentifier() const; 139 | /// @brief keeps important details about macro for printing to a file 140 | void set_macro_stat(); 141 | MacroStat const* get_macro_stat(); 142 | 143 | bool operator==(PPMacro const& mac) const; 144 | //bool operator==(token_type const& tok) const; 145 | //no less than operator should be defined but why?? 146 | bool operator<(PPMacro const& mac) const; 147 | 148 | private: 149 | bool HasLowerCase() const; 150 | bool HasLeadingUnderscore() const; 151 | 152 | private: 153 | typedef std::vector >vpTokInt; 154 | // the macro identifier token 155 | token_type identifier; 156 | //the complete macro -- operation + identifier +(args)opt + rep_text 157 | std::vector macro_tokens; 158 | //the complete identifier string including arguments 159 | std::string identifier_str; 160 | //keep the function_like PPMacro's arguments and their position 161 | vpTokInt identifier_parameters; 162 | PPOperation operation;//define or undefine etc... 163 | MacroCategory m_cat; //function like or object like etc... 164 | MacroScopeCategory m_scat;// inside function, inside class, etc... 165 | //log file to store all the errors and warnings etc. 166 | std::ostream& logFile; 167 | ReplacementList rep_list; 168 | CondCategory condCat;//either config or local 169 | // keep only the first use case 170 | std::pair use_case; 171 | std::vector invoArgs; 172 | bool use_case_set; 173 | MacroStat* m_stat; 174 | }; 175 | 176 | /** 177 | * @struct MacroOrder 178 | * @details Used to sort the macros in a map, the sorting is based on pointers 179 | * so as to handle multiple definitions 180 | */ 181 | struct MacroOrder 182 | { 183 | bool operator()(const PPMacro* m1, const PPMacro* m2=NULL) const 184 | { 185 | //comparing the pointers to handle multiple definitions 186 | if(m2==NULL) 187 | return true; 188 | return m1 < m2; 189 | } 190 | }; 191 | 192 | #endif /*MACRO_HPP*/ 193 | -------------------------------------------------------------------------------- /FileManager.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #include "Overseer.h" //observable 24 | #include "FileManager.h" 25 | #include "FileManagerScheme.h" 26 | #include "ExceptionHandler.h" 27 | 28 | FileManager::FileManager(FileManagerScheme const& fs, 29 | DemacroficationScheme const& ds) 30 | : fileManagerScheme(fs), 31 | demacroficationScheme(ds), 32 | inputFileIndex(0), 33 | outputFileIndex(0) 34 | { 35 | 36 | if(!SanityCheck()) 37 | throw ExceptionHandler("Failed Sanity Check in the File Manager"); 38 | PrepareMacroStatFile(); 39 | PrepareDemacrofiedMacroStatFile(); 40 | } 41 | 42 | void FileManager::Configure(FileManagerScheme const& fs) 43 | { 44 | //fileManagerScheme = fs; 45 | } 46 | 47 | std::vectorconst& FileManager::OutputFiles() 48 | { 49 | return fileManagerScheme.outputFiles; 50 | } 51 | 52 | std::vectorconst& FileManager::InputFiles() 53 | { 54 | return fileManagerScheme.inputFiles; 55 | } 56 | 57 | std::string const& FileManager::OutputDirectory() 58 | { 59 | return fileManagerScheme.outputDirectory; 60 | } 61 | 62 | std::string const& FileManager::InputDirectory() 63 | { 64 | return fileManagerScheme.inputDirectory; 65 | } 66 | 67 | //check whether this file is there in the list of output_files or not 68 | void FileManager::UpdateFile(std::ostream& fp, std::string const& file_str) 69 | { 70 | fp< const& FileManager::GetSearchPaths() const 145 | { 146 | return fileManagerScheme.searchPaths; 147 | } 148 | 149 | std::vector const& FileManager::GetInputFiles()const 150 | { 151 | return fileManagerScheme.inputFiles; 152 | } 153 | 154 | ///@todo perform checks 155 | bool FileManager::SanityCheck() 156 | { 157 | return true; 158 | } 159 | 160 | void FileManager::WriteLog(std::string const& str) 161 | { 162 | *(fileManagerScheme.pLogFile) << str << "\n"; 163 | } 164 | 165 | void FileManager::PrepareDemacrofiedMacroStatFile() 166 | { 167 | std::string header; 168 | if(demacroficationScheme.performCleanup){ 169 | header = "###################################################################\n" 170 | "#This file contains the details of each macro processed by the demacrofier\n" 171 | "#The file can be read by any yaml parser\n" 172 | "#The format is as follows:\n" 173 | "#file-name:" 174 | "# - id: identifier string\n" 175 | "###################################################################\n"; 176 | } 177 | 178 | else{ 179 | header = "###################################################################\n" 180 | "#This file contains the details of each macro processed by the demacrofier\n" 181 | "#The file can be read by any yaml parser\n" 182 | "#The format is as follows:\n" 183 | "#macro\n" 184 | "# - id: identifier string\n" 185 | "# - category: macro_category\n" 186 | "# - header_guard_string: string\n" 187 | "###################################################################\n"; 188 | } 189 | GetDemacrofiedMacroStatFile()<\n" 200 | "# - m_id : identifier string\n" 201 | "# - m_cat: macro_category\n" 202 | "# - c_cat: if the replacement text maps to C++ expression then c_cat is complete otherwise partial\n" 203 | "# - d_cat: if the replacement text contains free variable(s) then d_cat is dependent otherwise closed\n" 204 | "###################################################################\n"; 205 | 206 | 207 | GetMacroStatFile()< 47 | #include 48 | #include //for void Parser::GetDemacrofiedFile(std::ostream os) 49 | #include 50 | #include 51 | #include 52 | 53 | typedef std::map //replacement text 55 | MacroList_t; 56 | typedef Tuple4_t 57 | Tuple4MacroStat_t; 58 | 59 | /** forward declaration 60 | * @class CondParser 61 | */ 62 | class CondParser; 63 | 64 | /** forward declaration 65 | * @class RlParser 66 | */ 67 | class RlParser; 68 | 69 | /** forward declaration 70 | * @class Demacrofier 71 | */ 72 | class Demacrofier; 73 | 74 | /** forward declaration 75 | * @class DemacroficationScheme 76 | */ 77 | struct DemacroficationScheme; 78 | 79 | /** forward declaration 80 | * @class MacroStat 81 | */ 82 | struct MacroStat; 83 | 84 | /** 85 | * @class Parser 86 | */ 87 | class Parser { 88 | 89 | public: 90 | //Parser(); 91 | Parser(DemacroficationScheme const& demacrofication_scheme, 92 | std::ostream& log_file, std::ostream& macro_list_file); 93 | ~Parser(); 94 | void Parse(std::string file_name); 95 | void Parse(std::string file_name,ASTMacroStat_t* p, InvocationStat_t* is=NULL); 96 | 97 | void ParseNewGlobalMacros(std::string const& raw_global_macro_file_name); 98 | void ReadGlobalMacros(std::string const& global_macro_file_name); 99 | //Parser(std::string instr, position_type pos); 100 | 101 | MacTree const* GetMacTree(); 102 | /** @function Configure 103 | * for loading the configuration file dynamically 104 | */ 105 | void Configure(DemacroficationScheme const& demacrofication_scheme); 106 | 107 | void ParseMacros(MacroList_t& macro_list); 108 | void ParseGlobalMacros(); 109 | void ParseLocalMacros(std::string ifileStr, position_type pos); 110 | 111 | bool PPCheckIdentifier(std::string const& id_value) const; 112 | bool PPCheckIdentifier(std::string const& id_value, 113 | MacroList_t const& macro_list) const; 114 | void GetDemacrofiedFile(std::ostream& os); 115 | //std::stringstream const& GetDemacrofiedFile(); 116 | void PPAnalyzeMacroDependency(std::ostream& os); 117 | // when multiple occurences of same macros are allowed multiple_definitions=true 118 | void Demacrofy(std::ostream& stat, bool multiple_definitions=false); 119 | 120 | private: 121 | void InitializeMacTree(); 122 | void PPDefineHandler(MacroList_t& macro_list,PPMacro& macro_ref); 123 | std::string PPUndefHandler(MacroList_t& macro_list, PPMacro& macro_ref); 124 | void PPIfHandler(Node& node); 125 | void PPIfHandler(Node& node, bool def); 126 | void PPBuildMacroDependencyList(std::ostream& os); 127 | token_iterator GoPastMacro(token_iterator it); 128 | std::string FillCondTokens(std::vector const& cs); 129 | private: 130 | 131 | /** 132 | * Friend Classes: 133 | * @class CondParser; 134 | * @class Demacrofier; 135 | */ 136 | /// @todo friend to be removed from CondParser 137 | friend class CondParser; 138 | friend class Demacrofier; 139 | 140 | /// @brief pointer to the map passed by the Overseer class, 141 | /// this contains information collected by the clang front end. 142 | ASTMacroStat_t* pASTMacroStat; 143 | 144 | /// @brief contains line numbers whre the macros are invoked 145 | InvocationStat_t* pInvocationStat; 146 | 147 | /** 148 | * Variables initialized in the body of the constructor 149 | * @var CondParser* cp; 150 | * @var Demacrofier* demac; 151 | * @var token_iterator it;//current token 152 | * @var token_iterator it_begin;//first token 153 | * @var token_iterator it_end;//one past the last token 154 | */ 155 | CondParser* cp; 156 | RlParser* rp; 157 | Demacrofier* demac; 158 | token_iterator it;//current token 159 | token_iterator it_begin;//first token 160 | token_iterator it_end;//one past the last token 161 | /** 162 | * variables to be passed to the constructor to be called by the 163 | * Overseer class 164 | */ 165 | /// information for the parser and demacrofier on how to demacrofy 166 | DemacroficationScheme const* pDemacroficationScheme; 167 | /// log file to store all the errors and warnings etc. 168 | std::ostream& logFile; 169 | /// file to store the complete macro(identifier+repl_text) 170 | std::ostream& mlFile; 171 | /** 172 | * Variables initialized in the initializer list of the constructor 173 | * @var int nesting_level; 174 | * @var CondCategory condCat; 175 | * @var std::string fileGlobalMacros; 176 | */ 177 | 178 | /** 179 | * @var int nesting_level 180 | * @details nesting level is 0 for the predefined macros and 181 | * increases by 1 with each #if style block 182 | */ 183 | int nesting_level; 184 | /** 185 | * @var std::string fileGlobalMacros; 186 | * @details useful for passing around the conditional category(config/local) 187 | */ 188 | CondCategory condCat; 189 | 190 | /** 191 | * @var std::string fileGlobalMacros; 192 | * @details file containing global macros 193 | */ 194 | std::string fileGlobalMacros; 195 | 196 | /** 197 | * Other Variables: 198 | * @var std::vector condStmt; 199 | * @var MacroList_t localMacros; 200 | * @var MacroList_t globalMacros; 201 | * @var MacTree tree; 202 | * @var std::stringstream outStream; 203 | * @var std::string ifileStr; 204 | */ 205 | /// @brief useful for passing around the conditional statement 206 | std::vector condStmt; 207 | /// @brief list of macros in the current file 208 | MacroList_t localMacros; 209 | /// @brief list of predefined macros 210 | MacroList_t globalMacros; 211 | /// @brief make this a pointer to tree and dynamically allocate 212 | MacTree* pTree; 213 | /// @brief demacrofied file 214 | std::stringstream outStream; 215 | /// @brief the input file contents 216 | std::string ifileStr; 217 | /// @brief statistics 218 | unsigned int macro_count; 219 | unsigned int object_like_count; 220 | unsigned int function_like_count; 221 | std::vector vec_macro_stat; 222 | }; 223 | 224 | #endif /*PARSER_H*/ 225 | 226 | -------------------------------------------------------------------------------- /gConditions.h: -------------------------------------------------------------------------------- 1 | #define __DBL_MIN_EXP__ (-1021) 2 | #define __UINT_LEAST16_MAX__ 65535 3 | #define __FLT_MIN__ 1.17549435082228750797e-38F 4 | #define __UINT_LEAST8_TYPE__ unsigned char 5 | #define __INTMAX_C(c) c ## L 6 | #define __CHAR_BIT__ 8 7 | #define __UINT8_MAX__ 255 8 | #define __WINT_MAX__ 4294967295U 9 | #define __ORDER_LITTLE_ENDIAN__ 1234 10 | #define __SIZE_MAX__ 18446744073709551615UL 11 | #define __WCHAR_MAX__ 2147483647 12 | #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 13 | #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 14 | #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 15 | #define __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L) 16 | #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 17 | #define __FLT_EVAL_METHOD__ 0 18 | #define __unix__ 1 19 | #define __x86_64 1 20 | #define __UINT_FAST64_MAX__ 18446744073709551615UL 21 | #define __SIG_ATOMIC_TYPE__ int 22 | #define __DBL_MIN_10_EXP__ (-307) 23 | #define __FINITE_MATH_ONLY__ 0 24 | #define __GNUC_PATCHLEVEL__ 3 25 | #define __UINT_FAST8_MAX__ 255 26 | #define __DEC64_MAX_EXP__ 385 27 | #define __INT8_C(c) c 28 | #define __UINT_LEAST64_MAX__ 18446744073709551615UL 29 | #define __SHRT_MAX__ 32767 30 | #define __LDBL_MAX__ 1.18973149535723176502e+4932L 31 | #define __UINT_LEAST8_MAX__ 255 32 | #define __UINTMAX_TYPE__ long unsigned int 33 | #define __linux 1 34 | #define __DEC32_EPSILON__ 1E-6DF 35 | #define __unix 1 36 | #define __UINT32_MAX__ 4294967295U 37 | #define __LDBL_MAX_EXP__ 16384 38 | #define __WINT_MIN__ 0U 39 | #define __linux__ 1 40 | #define __SCHAR_MAX__ 127 41 | #define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) 42 | #define __INT64_C(c) c ## L 43 | #define __DBL_DIG__ 15 44 | #define _FORTIFY_SOURCE 2 45 | #define __SIZEOF_INT__ 4 46 | #define __SIZEOF_POINTER__ 8 47 | #define __USER_LABEL_PREFIX__ 48 | #define __STDC_HOSTED__ 1 49 | #define __LDBL_HAS_INFINITY__ 1 50 | #define __FLT_EPSILON__ 1.19209289550781250000e-7F 51 | #define __LDBL_MIN__ 3.36210314311209350626e-4932L 52 | #define __DEC32_MAX__ 9.999999E96DF 53 | #define __INT32_MAX__ 2147483647 54 | #define __SIZEOF_LONG__ 8 55 | #define __UINT16_C(c) c 56 | #define __DECIMAL_DIG__ 21 57 | #define __gnu_linux__ 1 58 | #define __LDBL_HAS_QUIET_NAN__ 1 59 | #define __GNUC__ 4 60 | #define __MMX__ 1 61 | #define __FLT_HAS_DENORM__ 1 62 | #define __SIZEOF_LONG_DOUBLE__ 16 63 | #define __BIGGEST_ALIGNMENT__ 16 64 | #define __DBL_MAX__ ((double)1.79769313486231570815e+308L) 65 | #define __INT_FAST32_MAX__ 9223372036854775807L 66 | #define __DBL_HAS_INFINITY__ 1 67 | #define __DEC32_MIN_EXP__ (-94) 68 | #define __INT_FAST16_TYPE__ long int 69 | #define __LDBL_HAS_DENORM__ 1 70 | #define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL 71 | #define __INT_LEAST32_MAX__ 2147483647 72 | #define __DEC32_MIN__ 1E-95DF 73 | #define __DBL_MAX_EXP__ 1024 74 | #define __DEC128_EPSILON__ 1E-33DL 75 | #define __SSE2_MATH__ 1 76 | #define __PTRDIFF_MAX__ 9223372036854775807L 77 | #define __amd64 1 78 | #define __LONG_LONG_MAX__ 9223372036854775807LL 79 | #define __SIZEOF_SIZE_T__ 8 80 | #define __SIZEOF_WINT_T__ 4 81 | #define __GCC_HAVE_DWARF2_CFI_ASM 1 82 | #define __GXX_ABI_VERSION 1002 83 | #define __FLT_MIN_EXP__ (-125) 84 | #define __INT_FAST64_TYPE__ long int 85 | #define __DBL_MIN__ ((double)2.22507385850720138309e-308L) 86 | #define __LP64__ 1 87 | #define __DECIMAL_BID_FORMAT__ 1 88 | #define __DEC128_MIN__ 1E-6143DL 89 | #define __REGISTER_PREFIX__ 90 | #define __UINT16_MAX__ 65535 91 | #define __DBL_HAS_DENORM__ 1 92 | #define __UINT8_TYPE__ unsigned char 93 | #define __NO_INLINE__ 1 94 | #define __FLT_MANT_DIG__ 24 95 | #define __VERSION__ "4.6.3" 96 | #define __UINT64_C(c) c ## UL 97 | #define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ 98 | #define __INT32_C(c) c 99 | #define __DEC64_EPSILON__ 1E-15DD 100 | #define __ORDER_PDP_ENDIAN__ 3412 101 | #define __DEC128_MIN_EXP__ (-6142) 102 | #define __INT_FAST32_TYPE__ long int 103 | #define __UINT_LEAST16_TYPE__ short unsigned int 104 | #define unix 1 105 | #define __INT16_MAX__ 32767 106 | #define __SIZE_TYPE__ long unsigned int 107 | #define __UINT64_MAX__ 18446744073709551615UL 108 | #define __INT8_TYPE__ signed char 109 | #define __ELF__ 1 110 | #define __FLT_RADIX__ 2 111 | #define __INT_LEAST16_TYPE__ short int 112 | #define __LDBL_EPSILON__ 1.08420217248550443401e-19L 113 | #define __UINTMAX_C(c) c ## UL 114 | #define __SSE_MATH__ 1 115 | #define __k8 1 116 | #define __SIG_ATOMIC_MAX__ 2147483647 117 | #define __SIZEOF_PTRDIFF_T__ 8 118 | #define __x86_64__ 1 119 | #define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF 120 | #define __INT_FAST16_MAX__ 9223372036854775807L 121 | #define __UINT_FAST32_MAX__ 18446744073709551615UL 122 | #define __UINT_LEAST64_TYPE__ long unsigned int 123 | #define __FLT_HAS_QUIET_NAN__ 1 124 | #define __FLT_MAX_10_EXP__ 38 125 | #define __LONG_MAX__ 9223372036854775807L 126 | #define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL 127 | #define __FLT_HAS_INFINITY__ 1 128 | #define __UINT_FAST16_TYPE__ long unsigned int 129 | #define __DEC64_MAX__ 9.999999999999999E384DD 130 | #define __CHAR16_TYPE__ short unsigned int 131 | #define __PRAGMA_REDEFINE_EXTNAME 1 132 | #define __INT_LEAST16_MAX__ 32767 133 | #define __DEC64_MANT_DIG__ 16 134 | #define __INT64_MAX__ 9223372036854775807L 135 | #define __UINT_LEAST32_MAX__ 4294967295U 136 | #define __INT_LEAST64_TYPE__ long int 137 | #define __INT16_TYPE__ short int 138 | #define __INT_LEAST8_TYPE__ signed char 139 | #define __DEC32_MAX_EXP__ 97 140 | #define __INT_FAST8_MAX__ 127 141 | #define __INTPTR_MAX__ 9223372036854775807L 142 | #define linux 1 143 | #define __SSE2__ 1 144 | #define __LDBL_MANT_DIG__ 64 145 | #define __DBL_HAS_QUIET_NAN__ 1 146 | #define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) 147 | #define __k8__ 1 148 | #define __INTPTR_TYPE__ long int 149 | #define __UINT16_TYPE__ short unsigned int 150 | #define __WCHAR_TYPE__ int 151 | #define __SIZEOF_FLOAT__ 4 152 | #define __UINTPTR_MAX__ 18446744073709551615UL 153 | #define __DEC64_MIN_EXP__ (-382) 154 | #define __INT_FAST64_MAX__ 9223372036854775807L 155 | #define __FLT_DIG__ 6 156 | #define __UINT_FAST64_TYPE__ long unsigned int 157 | #define __INT_MAX__ 2147483647 158 | #define __amd64__ 1 159 | #define __INT64_TYPE__ long int 160 | #define __FLT_MAX_EXP__ 128 161 | #define __ORDER_BIG_ENDIAN__ 4321 162 | #define __DBL_MANT_DIG__ 53 163 | #define __INT_LEAST64_MAX__ 9223372036854775807L 164 | #define __DEC64_MIN__ 1E-383DD 165 | #define __WINT_TYPE__ unsigned int 166 | #define __UINT_LEAST32_TYPE__ unsigned int 167 | #define __SIZEOF_SHORT__ 2 168 | #define __SSE__ 1 169 | #define __LDBL_MIN_EXP__ (-16381) 170 | #define __INT_LEAST8_MAX__ 127 171 | #define __SSP__ 1 172 | #define __SIZEOF_INT128__ 16 173 | #define __LDBL_MAX_10_EXP__ 4932 174 | #define __DBL_EPSILON__ ((double)2.22044604925031308085e-16L) 175 | #define _LP64 1 176 | #define __UINT8_C(c) c 177 | #define __INT_LEAST32_TYPE__ int 178 | #define __SIZEOF_WCHAR_T__ 4 179 | #define __UINT64_TYPE__ long unsigned int 180 | #define __INT_FAST8_TYPE__ signed char 181 | #define __DBL_DECIMAL_DIG__ 17 182 | #define __DEC_EVAL_METHOD__ 2 183 | #define __UINT32_C(c) c ## U 184 | #define __INTMAX_MAX__ 9223372036854775807L 185 | #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ 186 | #define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F 187 | #define __INT8_MAX__ 127 188 | #define __UINT_FAST32_TYPE__ long unsigned int 189 | #define __CHAR32_TYPE__ unsigned int 190 | #define __FLT_MAX__ 3.40282346638528859812e+38F 191 | #define __INT32_TYPE__ int 192 | #define __SIZEOF_DOUBLE__ 8 193 | #define __FLT_MIN_10_EXP__ (-37) 194 | #define __INTMAX_TYPE__ long int 195 | #define __DEC128_MAX_EXP__ 6145 196 | #define __GNUC_MINOR__ 6 197 | #define __UINTMAX_MAX__ 18446744073709551615UL 198 | #define __DEC32_MANT_DIG__ 7 199 | #define __DBL_MAX_10_EXP__ 308 200 | #define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L 201 | #define __INT16_C(c) c 202 | #define __STDC__ 1 203 | #define __PTRDIFF_TYPE__ long int 204 | #define __UINT32_TYPE__ unsigned int 205 | #define __UINTPTR_TYPE__ long unsigned int 206 | #define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD 207 | #define __DEC128_MANT_DIG__ 34 208 | #define __LDBL_MIN_10_EXP__ (-4931) 209 | #define __SIZEOF_LONG_LONG__ 8 210 | #define __LDBL_DIG__ 18 211 | #define __FLT_DECIMAL_DIG__ 9 212 | #define __UINT_FAST16_MAX__ 18446744073709551615UL 213 | #define __GNUC_GNU_INLINE__ 1 214 | #define __UINT_FAST8_TYPE__ unsigned char 215 | -------------------------------------------------------------------------------- /DepGraph.h: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #ifndef DEPGRAPH_H 24 | #define DEPGRAPH_H 25 | 26 | /** 27 | * @file DepGraph.h 28 | * @brief contains the node as well as the tree class for building 29 | * the dependency graph. This graph can then be traversed for dependency analysis etc. 30 | * @version 1.0 31 | * @author Aditya Kumar 32 | * @note 33 | * compiles with g++-4.5 or higher, 34 | * for compiling pass -std=c++0x to the compiler 35 | */ 36 | /** @todo how can the AST of if-else block be made generic 37 | * basically the graph has the following properties: 38 | * 1. siblings are connected. 39 | * 2. each level is a representation of nest depth. 40 | * 3. at one level each node will contain all the code/text that lies in between 41 | * it and it's sibling. 42 | * 4. 43 | */ 44 | #include "Macro.h" 45 | #include "DemacBoostWaveIncludes.h" 46 | #include "UseCaseState.h" 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | #include 55 | #include 56 | 57 | /** 58 | * @class Node 59 | * @brief Node of the macro tree used to store macros 60 | */ 61 | struct Node { 62 | //public: 63 | Node() 64 | : key(boost::wave::T_UNKNOWN), 65 | nodeIndex(0), 66 | condCat(CondCategory::local), 67 | parent(NULL) 68 | {} 69 | ~Node() 70 | { 71 | std::for_each(vecMacro.begin(),vecMacro.end(), 72 | [](PPMacro* mac) { 73 | delete mac; 74 | mac=NULL; 75 | }); 76 | } 77 | std::vector const& GetCondStmt() 78 | { 79 | return condStmt; 80 | } 81 | //put the macro in the free store 82 | void PushBackMacro(PPMacro& mac) 83 | { 84 | PPMacro* m = new PPMacro(mac); 85 | //*m = mac; 86 | vecMacro.push_back(m); 87 | } 88 | bool operator==(Node& n) 89 | { 90 | return (condStmt == n.condStmt) && 91 | (parent == n.parent) && 92 | (vecMacro == n.vecMacro); 93 | } 94 | 95 | token_type key;//this key may be #if, #ifdef, ifndef, endif 96 | int nodeIndex; 97 | //whether config macros used or local macros tested for 98 | CondCategory condCat; 99 | //the complete condition text including the #if etc... 100 | std::vector condStmt; 101 | //Macros within the condition block 102 | std::vector vecMacro;//keep only the pointer to macro 103 | Node* parent; 104 | }; 105 | 106 | /** 107 | * @struct NodeOrder 108 | * @brief To sort the Node 109 | */ 110 | struct NodeOrder { 111 | bool operator()(Node const* n1, Node const* n2 = NULL) const 112 | { 113 | if(n2==NULL) 114 | return true; 115 | return n1->nodeIndex < n2->nodeIndex; 116 | } 117 | }; 118 | 119 | typedef std::multimap TokenMacroMap_t; 120 | typedef std::pair PairMacroIter_t; 122 | 123 | //first arg: type of adjacency list, second arg: backbone of graph 124 | //Also defined in DepAnalyzer.h 125 | typedef boost::adjacency_list Graph_t; 127 | //Also defined in DepAnalyzer.h 128 | typedef boost::graph_traits::vertex_descriptor Vertex_t; 129 | 130 | typedef boost::graph_traits::vertex_iterator VertexIterator_t; 131 | typedef boost::graph_traits::out_edge_iterator OutEdgeIterator_t; 132 | 133 | //since we are storing pointers no need of a multimap 134 | typedef std::map NodeMap_t; 135 | 136 | // vector of pairs to retain the order in which they occur 137 | //also defined in the DepAnalyzer.h 138 | typedef std::vector > > DepList_t; 139 | 140 | //not used rite now 141 | class DFSVisitor : public boost::default_dfs_visitor 142 | { 143 | public: 144 | void discover_vertex(Vertex_t v, const Graph_t& g) const 145 | { 146 | /* for_each(g[v]->vecMacro.begin(),g[v]->vecMacro.End(), 147 | [&linearOrder](PPMacro mac) { 148 | linearOrder.push_back(&mac); 149 | });*/ 150 | } 151 | }; 152 | 153 | /** 154 | * @class MacTree 155 | * @brief The tree class having Node as vertices of the trees 156 | */ 157 | class MacTree { 158 | 159 | public: 160 | MacTree() 161 | :nodeIndex(0),depGraph(1) 162 | { 163 | Node* pn = new Node; 164 | //currVertex is dummy here 165 | NodeMap_t::iterator nodeMap_iter = 166 | nodeMap.insert(std::make_pair(pn,currVertex)).first; 167 | currVertex = boost::add_vertex(nodeMap_iter->first, depGraph); 168 | nodeMap_iter-> second = currVertex; 169 | startVertex = currVertex; 170 | } 171 | ~MacTree() 172 | { DeleteNodes(); } 173 | 174 | /// @brief get the root node 175 | Node const* GetRoot() const; 176 | 177 | /// @brief get the parent node 178 | Node* GetParent(Node* const np); 179 | 180 | /// @brief return the first child of the node, not implemented 181 | Node* GetFirstChild(Vertex_t const v); 182 | 183 | /// @brief get the total number of nodes 184 | int GetNumNodes(); 185 | 186 | /// @brief is the node a root node 187 | bool IsRoot(Vertex_t const v) const; 188 | 189 | /// @brief sibling of the currently pointed vertex 190 | bool MakeSibling(Node& np); 191 | 192 | /// @brief child to the currently pointed vertex 193 | bool MakeChild(Node& np); 194 | 195 | /// @brief specific to the macro insertion 196 | void PushBackMacro(PPMacro& mac); 197 | 198 | /// @brief returns the macro associated having the identifier token as tok 199 | PairMacroIter_t GetMacro(token_type const& tok); 200 | 201 | /// @brief sets the pointer of the current node to the parent node 202 | void GotoParent(); 203 | 204 | /// @brief builds the dependency list, and returns a refernce to it 205 | DepList_t const& BuildMacroDependencyList(); 206 | 207 | /// @brief gets the vertex descriptor to the parent of the current vertex 208 | Vertex_t GetParent(Vertex_t const v); 209 | 210 | /// @brief returns the pair of iterators to the siblings 211 | std::pair 212 | GetSiblings(Vertex_t const currV); 213 | 214 | /// @brief returns the pair of iterators to the children 215 | std::pair 216 | GetChildren(Vertex_t const currV); 217 | 218 | bool MakeChild(Vertex_t parentV, Vertex_t childV); 219 | bool MakeSibling(Vertex_t firstV,Vertex_t secondV); 220 | bool DeleteVertex(Vertex_t v); 221 | void DeleteNodes(); 222 | bool IsMacro(token_type const& tok); 223 | void CheckToken(token_iterator tok_iter); 224 | 225 | /// not defined: for future use 226 | Vertex_t GetAncestor(int nesting_level); 227 | 228 | /// algorithm 229 | void Dfs(Vertex_t const startV); 230 | /// algorithm 231 | void Bfs(Vertex_t const startV); 232 | /// algorithm 233 | void TopSort(std::vector& topo_order); 234 | 235 | private: 236 | int nodeIndex; 237 | NodeMap_t nodeMap; 238 | std::vector linearOrder;//keeps the macro order as they occur 239 | UseCaseState macroUseCaseState; 240 | TokenMacroMap_t tokenMacroMap; 241 | DepList_t macroDepList; 242 | Graph_t depGraph; 243 | Vertex_t currVertex; 244 | Vertex_t startVertex;//the root node 245 | }; 246 | 247 | #endif /*DEPGRAPH_H*/ 248 | -------------------------------------------------------------------------------- /ClangInterface/TrackMacro.cpp: -------------------------------------------------------------------------------- 1 | #include "TrackMacro.hpp" 2 | #include "debug.h" 3 | 4 | std::ostream& operator<<(std::ostream& os, const CollectedMacroInfo& cmi) 5 | { 6 | os<<"::"; 7 | os<isInMainFile(MI->getDefinitionLoc())) { 31 | PresumedLoc presumed = sm->getPresumedLoc(Range.getBegin()); 32 | CLANG_AST_DEBUG(dbgs() << "\nMacro " 33 | << MacroNameTok.getIdentifierInfo()->getNameStart() 34 | << " has expanded at line# " << presumed.getLine();); 35 | 36 | //NOTE PresumedLoc can be modified by the LINE directive 37 | 38 | ASTMacroStat[MacroNameTok.getIdentifierInfo()-> 39 | getNameStart()].invoked_lines.push_back(presumed.getLine()); 40 | 41 | // put the line number of invocation in m_istat 42 | // i think it is not useful anymore 43 | m_istat->insert(presumed.getLine()); 44 | 45 | CLANG_AST_DEBUG(dbgs() << "arguments are:"; 46 | for(auto arg_it = MI->arg_begin(); 47 | arg_it != MI->arg_end(); ++arg_it) 48 | dbgs() << (*arg_it)->getNameStart() << "\t";); 49 | 50 | //if(MacroIsLocal(Range.getBegin())) { 51 | if(MI->isFunctionLike()){ 52 | /* std::cout<<"The macro " 53 | <getNameStart() 54 | <<" is function like\n"; */ 55 | } 56 | } 57 | /* 58 | if(MI->isObjectLike()) 59 | std::cout<<"The macro is object like\n"; 60 | if(MI->isVariadic()) 61 | std::cout<<"The macro is variadic\n"; 62 | }*/ 63 | } 64 | 65 | /// PPCallback 66 | void TrackMacro::MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) 67 | { 68 | const MacroInfo* MI = MD->getMacroInfo(); 69 | //if(MacroIsLocal(MI->getDefinitionLoc())) { 70 | CollectedMacroInfo cmi; 71 | if(sm->isInMainFile(MI->getDefinitionLoc())) { 72 | PresumedLoc presumed = sm->getPresumedLoc(MI->getDefinitionLoc()); 73 | 74 | CLANG_AST_DEBUG(dbgs() << "Macro " 75 | << MacroNameTok.getIdentifierInfo()->getNameStart() 76 | << " is defined at line number: " 77 | << presumed.getLine() << "\n";); 78 | 79 | cmi.defined_line = presumed.getLine(); 80 | //std::cout<<"Macro "<isFunctionLike()){ 82 | cmi.m_cat = MacroCategory::function_like; 83 | //std::cout<<"The macro is function like: "; 84 | } 85 | if(MI->isObjectLike()){ 86 | cmi.m_cat = MacroCategory::object_like; 87 | //std::cout<<"The macro is object like\n"; 88 | } 89 | if(MI->isVariadic()){ 90 | cmi.m_cat = MacroCategory::variadic; 91 | //std::cout<<"The macro is variadic\n"; 92 | } 93 | ASTMacroStat[MacroNameTok.getIdentifierInfo()->getNameStart()] = cmi; 94 | } 95 | } 96 | 97 | /// PPCallback 98 | bool TrackMacro::FileNotFound(StringRef FileName, SmallVectorImpl& RecoveryPath) 99 | { 100 | std::string path = "/usr/include"; 101 | RecoveryPath.append(path.begin(),path.end()); 102 | /* for(int i = 0; igetFileID(loc); 112 | //std::cout<<"file id = "<getBufferName(loc)){ 115 | //PresumedLoc presumed = sm->getPresumedLoc(loc); 116 | //if(file_name == presumed.getFilename()) 117 | return true; 118 | } 119 | return false; 120 | } 121 | 122 | void TrackMacro::SetFileName(const std::string & f) 123 | { 124 | file_name = f; 125 | //std::cout<<"File name in TrackMacro set to: "<getSourceManager()); 147 | } 148 | 149 | void TrackMacro::SetCompilerInstance(const CompilerInstance* p) 150 | { 151 | pci = p; 152 | } 153 | 154 | void TrackMacro::PrintStats() 155 | { 156 | //using namespace general_utilities; 157 | std::map::const_iterator i = ASTMacroStat.begin(); 158 | for(; i!= ASTMacroStat.end(); ++i){ 159 | std::cout<first; 160 | std::cout<<"\t"; 161 | std::cout<second; 162 | std::cout<<"\n"; 163 | } 164 | //std::cout<const & FunctionInfo) 168 | { 169 | std::map::const_iterator fi_iter = FunctionInfo.begin(); 170 | std::map::iterator ms; 171 | std::map FunctionDefinitionRange; 172 | std::map::iterator fdr_iter; 173 | const int start = 0; 174 | const int end = 1; 175 | /// collect all the start line numbers of function, and sort them 176 | for( ; fi_iter != FunctionInfo.end(); ++fi_iter) { 177 | CLANG_AST_DEBUG(dbgs() << "Function: " << fi_iter->first 178 | << ", definition range is: (" 179 | <<(fi_iter->second).start_line << "," 180 | << (fi_iter->second).end_line << ")\n";); 181 | FunctionDefinitionRange[(fi_iter->second).start_line] = start; 182 | FunctionDefinitionRange[(fi_iter->second).end_line] = end; 183 | } 184 | // adding a dummy entry at the end so that all the entries will 185 | // have a lower bound 186 | FunctionDefinitionRange[std::numeric_limits::max()] = start; 187 | /// compare if the macro is defined after the function start line 188 | /// if yes then is it before the function end line. 189 | ms = ASTMacroStat.begin(); 190 | for( ; ms != ASTMacroStat.end(); ++ms) { 191 | fdr_iter = FunctionDefinitionRange.lower_bound((ms->second).defined_line); 192 | // no need to check if fdr_iter is FunctionDefinitionRange.end() or not 193 | // because of an extra entry 194 | 195 | CLANG_AST_DEBUG(dbgs() << "For macro: " << ms->first 196 | << ", defined line is: " << (ms->second).defined_line 197 | << ", the range returned is: (" 198 | << fdr_iter->first << "," 199 | << fdr_iter->second << ")\n";); 200 | 201 | if(fdr_iter->second == end) { 202 | (ms->second).s_cat.inside_function = true; 203 | CLANG_AST_DEBUG(dbgs() << "Macro: " << ms->first 204 | << ", is inside function\n";); 205 | } 206 | } 207 | } 208 | 209 | void TrackMacro:: 210 | VerifyMacroScope(std::mapconst & FunctionInfo) 211 | { 212 | std::map::const_iterator fi = FunctionInfo.begin(); 213 | std::map::iterator ms; 214 | for( ; fi != FunctionInfo.end(); ++fi) { 215 | ms = ASTMacroStat.begin(); 216 | for( ; ms != ASTMacroStat.end(); ++ms) { 217 | if((ms->second).defined_line > (fi->second).start_line 218 | && (ms->second).defined_line < (fi->second).end_line) { 219 | (ms->second).s_cat.inside_function = true; 220 | CLANG_AST_DEBUG(dbgs() << "Macro: " << ms->first 221 | << ", is inside function " << fi->first << "\n";); 222 | } 223 | } 224 | } 225 | } 226 | 227 | ASTMacroStat_t& TrackMacro::GetMacroStat() 228 | { 229 | return ASTMacroStat; 230 | } 231 | 232 | /// collect all the line numbers where the macros have been invoked in a file 233 | /// the collection will be sorted in a multimap 234 | /// this will help in verifying if two macros are invoked on the same line 235 | /// if the macros are invoked on the same line I assume that they 236 | /// are nested and hence not transform it. 237 | 238 | /// return by value, relying on the move semantics of C++11 239 | InvocationStat_t* TrackMacro::GetInvocationStat() 240 | { 241 | return m_istat; 242 | /* 243 | //std::cout<<"Inserting:\n"; 244 | // this will leak make a smart pointer 245 | InvocationStat_t* is = new InvocationStat_t; 246 | auto iter = ASTMacroStat.begin(); 247 | for(; iter!=ASTMacroStat.end(); ++iter) { 248 | /// for each macro collect all the points of invocation 249 | std::for_each((iter->second).invoked_lines.begin(), 250 | (iter->second).invoked_lines.end(), 251 | [&is](int i) { 252 | //std::cout<insert(i); 254 | }); 255 | } 256 | return is;*/ 257 | } 258 | 259 | }// namespace clang 260 | -------------------------------------------------------------------------------- /DepGraph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | cpp2cxx is an open source software distributed under terms of the 3 | Apache2.0 licence. 4 | 5 | Copyrights remain with the original copyright holders. 6 | Use of this material is by permission and/or license. 7 | 8 | Copyright [2012] Aditya Kumar, Andrew Sutton, Bjarne Stroustrup 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | */ 22 | 23 | #include "DepGraph.h" 24 | #include "ExceptionHandler.h" 25 | #include "debug.h" 26 | 27 | #include // make_pair 28 | #include 29 | #include 30 | 31 | Node* MacTree::GetParent(Node* const np) 32 | { 33 | return np->parent; 34 | } 35 | 36 | Vertex_t MacTree::GetParent(Vertex_t const v) 37 | {//in a uni-directed graph incoming edge can't be accessed 38 | Node* cn; 39 | Node* pn; 40 | cn = depGraph[v]; 41 | pn = cn->parent; 42 | DEBUG_TREE(dbgs()<<"Parent nodeIndex: "<nodeIndex<<"\n";); 43 | //std::map::iterator nodeMap_iter; 44 | NodeMap_t::iterator nodeMap_iter = nodeMap.find(pn); 45 | return nodeMap_iter->second; 46 | } 47 | 48 | Node const* MacTree::GetRoot() const 49 | { 50 | return depGraph[startVertex]; 51 | } 52 | /* 53 | Node* MacTree::GetFirstChild(Vertex_t const currV) 54 | { 55 | return depGraph([boost::out_edges(currV,depGraph)).first]; 56 | } 57 | */ 58 | std::pair 59 | MacTree::GetSiblings(Vertex_t const vd) 60 | { 61 | Vertex_t v = GetParent(vd); 62 | return boost::out_edges(v,depGraph); 63 | } 64 | 65 | std::pair 66 | MacTree::GetChildren(Vertex_t const vd) 67 | { 68 | return boost::out_edges(vd,depGraph); 69 | } 70 | 71 | int MacTree::GetNumNodes() 72 | { 73 | return nodeIndex; 74 | } 75 | 76 | bool MacTree::IsRoot(Vertex_t const vd) const 77 | { 78 | return vd == startVertex; 79 | } 80 | 81 | //sibling of the currently pointed vertex 82 | bool MacTree::MakeSibling(Node& rn) 83 | { 84 | DEBUG_TREE(dbgs()<<"\nMaking sibling: "<parent = depGraph[u]; 93 | pn->nodeIndex = ++nodeIndex; 94 | NodeMap_t::iterator nodeMap_iter; 95 | //map::insert() returns pair 96 | nodeMap_iter = nodeMap.insert(std::make_pair(pn,v_dummy)).first; 97 | //add the pointer to node to the multimap 98 | //and capturing the returned vertex descriptor 99 | Vertex_t v = boost::add_vertex(nodeMap_iter->first, depGraph); 100 | nodeMap_iter-> second = v;//now assigning the vertex descriptor 101 | //return if the edge was created or it was already there 102 | //add edge returns a pair 103 | //Vertex_t u = GetParent(currVertex); 104 | bool new_edge = boost::add_edge(u,v,depGraph).second; 105 | currVertex = nodeMap_iter-> second; 106 | 107 | DEBUG_TREE(dbgs()<<"Node Number: "<nodeIndex<<"\n"; 108 | dbgs()<<"n_ptr: allocated: "<first<<"\n";); 110 | return new_edge; 111 | } 112 | 113 | //child to the currently pointed vertex 114 | bool MacTree::MakeChild(Node& rn) 115 | { 116 | DEBUG_TREE(dbgs()<<"\nMaking child: "<parent = depGraph[currVertex]; 122 | pn->nodeIndex = ++nodeIndex; 123 | NodeMap_t::iterator nodeMap_iter; 124 | nodeMap_iter = nodeMap.insert(std::make_pair(pn,v_dummy)).first; 125 | Vertex_t v = boost::add_vertex(nodeMap_iter->first, depGraph); 126 | nodeMap_iter-> second = v;//now assigning the vertex descriptor 127 | //return if the edge was created or it was already there 128 | //add edge returns a pair 129 | bool new_edge = boost::add_edge(currVertex,v,depGraph).second; 130 | currVertex = nodeMap_iter-> second; 131 | DEBUG_TREE(dbgs()<<"Node Number: "<nodeIndex<<"\n"; 132 | dbgs()<<"n_ptr: allocated: "<first<<"\n";); 134 | return new_edge; 135 | } 136 | 137 | bool MacTree::MakeChild(Vertex_t parentV, Vertex_t childV) 138 | { 139 | currVertex = childV; 140 | DEBUG_TREE(dbgs()<<"\nMaking child\n";); 141 | //return if the edge was created or it was already there 142 | return boost::add_edge(parentV,childV,depGraph).second; 143 | } 144 | 145 | bool MacTree::MakeSibling(Vertex_t firstV,Vertex_t secondV) 146 | { 147 | currVertex = secondV; 148 | DEBUG_TREE(dbgs()<<"Making sibling\n";); 149 | //return if the edge was created or it was already there 150 | Vertex_t v = GetParent(firstV); 151 | return boost::add_edge(v,secondV,depGraph).second; 152 | } 153 | 154 | void MacTree::PushBackMacro(PPMacro& mac) 155 | { 156 | DEBUG_TREE(dbgs()<<"Pushing Macro: "<PushBackMacro(mac); 158 | //get the pointer to the macro 159 | PPMacro* m_ptr; 160 | m_ptr = depGraph[currVertex]->vecMacro.back(); 161 | linearOrder.push_back(m_ptr); 162 | tokenMacroMap.insert(std::pair(m_ptr->get_identifier(),m_ptr)); 163 | } 164 | 165 | DepList_t const& MacTree::BuildMacroDependencyList() 166 | { 167 | PPMacro* m_ptr; 168 | std::list id_list; 169 | std::list::iterator id_list_iter; 170 | std::stringstream err_msg; 171 | TokenMacroMap_t::iterator tmm_iter; 172 | tmm_iter = tokenMacroMap.begin(); 173 | std::vector::iterator mp_iter; 174 | mp_iter = linearOrder.begin(); 175 | //putting the macros in macroDepList as they occur 176 | for(; mp_iter != linearOrder.end(); mp_iter++) { 177 | m_ptr = *mp_iter; 178 | //every loop should have a new instance to do away with emptying 179 | std::vector vec_mp; 180 | DEBUG_TREE(dbgs()<<"Processing Macro: "<get_identifier_str()<<"\n";); 181 | 182 | id_list = m_ptr->get_replacement_list_dep_idlist(); 183 | id_list_iter = id_list.begin(); 184 | for(; id_list_iter != id_list.end();id_list_iter++) { 185 | tmm_iter = tokenMacroMap.find(*id_list_iter); 186 | //check if the token was not found 187 | try { 188 | if(tmm_iter != tokenMacroMap.end()) { 189 | vec_mp.push_back(tmm_iter->second);//if macro found 190 | } 191 | else {//if not then throw the error 192 | err_msg << "Exception Line Number: " 193 | << id_list_iter->get_position().get_line() 194 | << ", No macro found for token: " 195 | << id_list_iter->get_value()<<"\n"; 196 | throw ExceptionHandler(err_msg.str()); 197 | } 198 | } catch(ExceptionHandler &e) { 199 | std::cout< vp; 217 | //vertices(g) returns the pair of vertex iterators 218 | //the first one points to the first vertex 219 | //the second points past the end of the last vertex 220 | //dereferencing the vertex iterator gives the vertex object 221 | for(vp = vertices(depGraph); vp.first != vp.second; ++vp.first) { 222 | delete depGraph[*(vp.first)]; 223 | } 224 | } 225 | 226 | bool MacTree::DeleteVertex(Vertex_t v) 227 | { 228 | //first delete all the macros in the node as they are allocated on the store 229 | if(v == startVertex) 230 | return false; 231 | if(currVertex == v) 232 | currVertex = GetParent(v);//point to the parent now 233 | //not deleting the node now, 234 | //will delete the node during destruction via nodeMap 235 | boost::clear_vertex(v,depGraph); 236 | boost::remove_vertex(v,depGraph); 237 | return true; 238 | } 239 | 240 | PairMacroIter_t MacTree::GetMacro(token_type const& tok) 241 | { 242 | return tokenMacroMap.equal_range(tok); 243 | } 244 | 245 | bool MacTree::IsMacro(token_type const& tok) 246 | { 247 | PairMacroIter_t m_iter = GetMacro(tok); 248 | //if there is atleast a macro with the token_type tok as identifier 249 | if(m_iter.first != m_iter.second) 250 | return true; 251 | else 252 | return false; 253 | } 254 | 255 | //checks the token to get the use case of macro 256 | void MacTree::CheckToken(token_iterator tok_iter) 257 | { 258 | PairMacroIter_t pm_iter = GetMacro(*tok_iter); 259 | 260 | //if there is no macro corresponding to this token 261 | 262 | if(pm_iter.first == pm_iter.second) { 263 | DEBUG_MACRO_USE_CASE(dbgs()<<"Putting token into the existing state:\n";); 264 | //are we collecting tokens in a macro invocation 265 | if(macroUseCaseState.DoneCollection()) { 266 | return; 267 | } 268 | else 269 | macroUseCaseState.PutToken(tok_iter); 270 | } 271 | else { 272 | /// @todo this token is a macro we are taking the first entry 273 | /// of the multimap which keeps macro 274 | /// *********collecting the args of function like macro ********** 275 | if(pm_iter.first->second->is_function_like()) { 276 | macroUseCaseState.PutArgBegin(tok_iter, pm_iter.first->second); 277 | } 278 | } 279 | } 280 | 281 | //algorithms 282 | void MacTree::Dfs(Vertex_t const startV) 283 | { 284 | //boost::depth_first_search(depGraph); 285 | } 286 | 287 | void MacTree::Bfs(Vertex_t const startV) 288 | { 289 | 290 | } 291 | 292 | void MacTree::TopSort(std::vector& topo_order) 293 | { 294 | boost::topological_sort(depGraph,std::back_inserter(topo_order)); 295 | } 296 | --------------------------------------------------------------------------------