| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2013-01-28 17:12:19 +01:00
										 |  |  | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Contact: http://www.qt-project.org/legal
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and Digia.  For licensing terms and | 
					
						
							|  |  |  | ** conditions see http://qt.digia.com/licensing.  For further information
 | 
					
						
							|  |  |  | ** use the contact form at http://qt.digia.com/contact-us.
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** In addition, as a special exception, Digia gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in the Digia Qt LGPL Exception | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  | #include "Preprocessor.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-13 17:37:33 +02:00
										 |  |  | #include <CPlusPlus.h>
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <cstdlib>
 | 
					
						
							| 
									
										
										
										
											2009-12-15 16:38:33 +01:00
										 |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  | enum { BLOCK_SIZE = 4 * 1024}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void parse(const char *fileName, const char *source, unsigned size); | 
					
						
							|  |  |  | int runWithSystemPreprocessor(int argc, char *argv[]); | 
					
						
							|  |  |  | int runWithNewPreprocessor(int argc, char *argv[]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:31:15 +02:00
										 |  |  | struct V: public ASTVisitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   V(TranslationUnit *unit) | 
					
						
							|  |  |  |     : ASTVisitor(unit) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   virtual bool visit(FunctionDeclaratorAST *ast) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (ast->as_cpp_initializer) { | 
					
						
							| 
									
										
										
										
											2010-08-26 16:16:22 +02:00
										 |  |  |       if (! (ast->symbol && ast->symbol->enclosingScope())) | 
					
						
							|  |  |  |         ; //translationUnit()->warning(ast->firstToken(), "resolved as function declaration");
 | 
					
						
							|  |  |  |       else if (ast->symbol->enclosingScope()->isNamespace() || ast->symbol->enclosingScope()->isTemplate()) | 
					
						
							|  |  |  |         ; //translationUnit()->warning(ast->firstToken(), "resolved as function declaration");
 | 
					
						
							|  |  |  |       else if (ast->symbol->enclosingScope()->isBlock()) | 
					
						
							|  |  |  |         ; //translationUnit()->warning(ast->firstToken(), "resolved as C++ initializer");
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:31:15 +02:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2010-08-26 16:16:22 +02:00
										 |  |  |         translationUnit()->warning(ast->firstToken(), "ambiguous function declarator or C++ intializer"); | 
					
						
							| 
									
										
										
										
											2010-08-26 10:31:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   virtual bool visit(ExpressionOrDeclarationStatementAST *ast) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     translationUnit()->warning(ast->firstToken(), "ambiguous expression or declaration statement"); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | int main(int argc, char *argv[]) | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (getenv("CPLUSPLUS_WITH_NEW_PREPROCESSOR")) | 
					
						
							|  |  |  |         return runWithNewPreprocessor(argc, argv); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return runWithSystemPreprocessor(argc, argv); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int runWithSystemPreprocessor(int argc, char *argv[]) | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     std::string cmdline; | 
					
						
							| 
									
										
										
										
											2010-08-26 10:31:15 +02:00
										 |  |  |     cmdline += "gcc -E -xc++ -U__BLOCKS__ -D__restrict= -D__restrict__= -D__extension__= -D__imag__= -D__real__= -D__complex__= -D_Complex= -D__signed=signed"; | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 1; i < argc; ++i) { | 
					
						
							|  |  |  |         cmdline += ' '; | 
					
						
							|  |  |  |         cmdline += argv[i]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char block[BLOCK_SIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  |     std::string preprocessedCode; | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (FILE *fp = popen(cmdline.c_str(), "r")) { | 
					
						
							|  |  |  |         while (size_t sz = fread(block, 1, BLOCK_SIZE, fp)) | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  |             preprocessedCode.append(block, sz); | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         pclose(fp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         fprintf(stderr, "c++: No such file or directory\n"); | 
					
						
							|  |  |  |         return EXIT_FAILURE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  |     parse("<stdin>", preprocessedCode.c_str(), preprocessedCode.size()); | 
					
						
							|  |  |  |     return EXIT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int runWithNewPreprocessor(int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (argc == 1) { | 
					
						
							|  |  |  |         fprintf(stderr, "c++: No such file or directory\n"); | 
					
						
							|  |  |  |         return EXIT_FAILURE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char block[BLOCK_SIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (FILE *fp = fopen(argv[1], "r")) { | 
					
						
							|  |  |  |         while (size_t sz = fread(block, 1, BLOCK_SIZE, fp)) | 
					
						
							|  |  |  |             source.append(block, sz); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fclose(fp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         fprintf(stderr, "c++: No such file or directory\n"); | 
					
						
							|  |  |  |         return EXIT_FAILURE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::ostringstream out; | 
					
						
							|  |  |  |     Preprocessor pp(out); | 
					
						
							|  |  |  |     pp(source.c_str(), source.size(), StringRef(argv[1])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const std::string preprocessedCode = out.str(); | 
					
						
							|  |  |  |     parse(argv[1], preprocessedCode.c_str(), preprocessedCode.size()); | 
					
						
							|  |  |  |     return EXIT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void parse(const char *fileName, const char *source, unsigned size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  |     Control control; | 
					
						
							| 
									
										
										
										
											2010-08-11 16:12:07 +02:00
										 |  |  |     TranslationUnit unit(&control, control.stringLiteral(fileName)); | 
					
						
							| 
									
										
										
										
											2009-12-15 16:49:59 +01:00
										 |  |  |     unit.setSource(source, size); | 
					
						
							| 
									
										
										
										
											2012-02-02 13:39:24 +01:00
										 |  |  |     unit.setCxxOxEnabled(true); | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  |     unit.parse(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:31:15 +02:00
										 |  |  | #if 1
 | 
					
						
							| 
									
										
										
										
											2010-08-13 14:00:27 +02:00
										 |  |  |     Namespace *globalNamespace = control.newNamespace(0); | 
					
						
							|  |  |  |     Bind bind(&unit); | 
					
						
							|  |  |  |     bind(unit.ast()->asTranslationUnit(), globalNamespace); | 
					
						
							| 
									
										
										
										
											2010-08-26 10:31:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     V v(&unit); | 
					
						
							|  |  |  |     v.accept(unit.ast()); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-10-23 12:58:39 +02:00
										 |  |  | } |