Files
qt-creator/src/libs/3rdparty/cplusplus/TranslationUnit.h

197 lines
6.2 KiB
C
Raw Normal View History

2008-12-02 12:01:29 +01:00
// Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef CPLUSPLUS_TRANSLATIONUNIT_H
#define CPLUSPLUS_TRANSLATIONUNIT_H
#include "CPlusPlusForwardDeclarations.h"
#include "ASTfwd.h"
#include "Token.h"
2010-08-10 17:30:20 +02:00
#include "DiagnosticClient.h"
#include <cstdio>
#include <vector>
C++: Core changes in preprocessing Summary of most relevant items: - Preprocessor output format change. No more gen true/false. Instead a more intuitive and natural expansion (like from a real compiler) is performed directly corresponding to the macro invocation. Notice that information about the generated tokens is not lost, because it's now embedded in the expansion section header (in terms of lines and columns as explained in the code). In addition the location on where the macro expansion happens is also documented for future use. - Fix line control directives and associated token line numbers. This was not detected in tests cases because some of them were actually wrong: Within expansions the line information was being considered as originally computed in the macro definition, while the desired and expected for Creator's reporting mechanism (just like regular compilers) is the line from the expanded version of the tokens. - Do not allow for eager expansion. This was previously being done inside define directives. However, it's not allowed and might lead to incorrect results, since the argument substitution should only happen upon the macro invocation (and following nested ones). At least GCC and clang are consistent with that. See test case tst_Preprocessor:dont_eagerly_expand for a detailed explanation. - Revive the 'expanded' token flag. This is used to mark every token that originates from a macro expansion. Notice, however, that expanded tokens are not necessarily generated tokens (although every generated token is a expanded token). Expanded tokens that are not generated are those which are still considered by our code model features, since they are visible on the editor. The translation unit is smart enough to calculate line/column position for such tokens based on the information from the expansion section header. - How expansions are tracked has also changed. Now, we simply add two surrounding marker tokens to each "top-level" expansion sequence. There is an enumeration that control expansion states. Also, no "previous" token is kept around. - Preprocessor client methods suffered a change in signature so they now receive the line number of the action in question as a paramater. Previously such line could be retrieved by the client implementation by accessing the environment line. However, this is not reliable because we try to avoid synchronization of the output/environment lines in order to avoid unnecessary output, while expanding macros or handling preprocessor directives. - Although macros are not expanded during define directives (as mentioned above) the preprocessor client is now "notified" when it sees a macro. This is to allow usage tracking. - Other small stuff. This is all in one patch because the fixes are a consequence of the change in preprocessing control. Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
#include <map>
namespace CPlusPlus {
2008-12-02 12:01:29 +01:00
class CPLUSPLUS_EXPORT TranslationUnit
{
TranslationUnit(const TranslationUnit &other);
void operator =(const TranslationUnit &other);
public:
2009-12-01 11:33:13 +01:00
TranslationUnit(Control *control, const StringLiteral *fileId);
2008-12-02 12:01:29 +01:00
~TranslationUnit();
Control *control() const;
2009-12-01 11:33:13 +01:00
const StringLiteral *fileId() const;
2008-12-02 12:01:29 +01:00
const char *fileName() const;
unsigned fileNameLength() const;
const char *firstSourceChar() const;
const char *lastSourceChar() const;
unsigned sourceLength() const;
void setSource(const char *source, unsigned size);
unsigned tokenCount() const;
const Token &tokenAt(unsigned index) const;
int tokenKind(unsigned index) const;
const char *spell(unsigned index) const;
2008-12-02 12:01:29 +01:00
unsigned commentCount() const;
const Token &commentAt(unsigned index) const;
2008-12-02 12:01:29 +01:00
unsigned matchingBrace(unsigned index) const;
2009-12-01 11:33:13 +01:00
const Identifier *identifier(unsigned index) const;
const Literal *literal(unsigned index) const;
const StringLiteral *stringLiteral(unsigned index) const;
const NumericLiteral *numericLiteral(unsigned index) const;
2008-12-02 12:01:29 +01:00
MemoryPool *memoryPool() const;
AST *ast() const;
2008-12-02 12:01:29 +01:00
bool blockErrors() const { return f._blockErrors; }
2008-12-02 12:01:29 +01:00
bool blockErrors(bool block);
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool onoff);
2010-03-24 12:54:25 +01:00
bool cxx0xEnabled() const;
void setCxxOxEnabled(bool onoff);
2009-01-09 16:55:25 +01:00
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
2008-12-02 12:01:29 +01:00
void warning(unsigned index, const char *fmt, ...);
void error(unsigned index, const char *fmt, ...);
void fatal(unsigned index, const char *fmt, ...);
2010-08-10 17:30:20 +02:00
void message(DiagnosticClient::Level level, unsigned index,
const char *format, va_list ap);
2008-12-02 12:01:29 +01:00
bool isTokenized() const;
void tokenize();
bool skipFunctionBody() const;
void setSkipFunctionBody(bool skipFunctionBody);
bool isParsed() const;
enum ParseMode {
ParseTranlationUnit,
ParseDeclaration,
ParseExpression,
2009-03-30 15:07:30 +02:00
ParseDeclarator,
ParseStatement
};
bool parse(ParseMode mode = ParseTranlationUnit);
2008-12-02 12:01:29 +01:00
void resetAST();
void release();
2009-06-24 16:40:30 +02:00
void getTokenStartPosition(unsigned index, unsigned *line,
unsigned *column = 0,
2009-12-01 11:33:13 +01:00
const StringLiteral **fileName = 0) const;
2009-06-24 16:40:30 +02:00
void getTokenEndPosition(unsigned index, unsigned *line,
unsigned *column = 0,
2009-12-01 11:33:13 +01:00
const StringLiteral **fileName = 0) const;
2009-06-24 16:40:30 +02:00
2008-12-02 12:01:29 +01:00
void getPosition(unsigned offset,
unsigned *line,
unsigned *column = 0,
2009-12-01 11:33:13 +01:00
const StringLiteral **fileName = 0) const;
2008-12-02 12:01:29 +01:00
void getTokenPosition(unsigned index,
unsigned *line,
unsigned *column = 0,
2009-12-01 11:33:13 +01:00
const StringLiteral **fileName = 0) const;
2008-12-02 12:01:29 +01:00
void pushLineOffset(unsigned offset);
void pushPreprocessorLine(unsigned offset,
unsigned line,
2009-12-01 11:33:13 +01:00
const StringLiteral *fileName);
2008-12-02 12:01:29 +01:00
2009-06-02 14:56:03 +02:00
unsigned findPreviousLineOffset(unsigned tokenIndex) const;
bool maybeSplitGreaterGreaterToken(unsigned tokenIndex);
private:
2008-12-02 12:01:29 +01:00
struct PPLine {
unsigned offset;
unsigned line;
2009-12-01 11:33:13 +01:00
const StringLiteral *fileName;
2008-12-02 12:01:29 +01:00
PPLine(unsigned offset = 0,
unsigned line = 0,
2009-12-01 11:33:13 +01:00
const StringLiteral *fileName = 0)
2008-12-02 12:01:29 +01:00
: offset(offset), line(line), fileName(fileName)
{ }
bool operator == (const PPLine &other) const
{ return offset == other.offset; }
bool operator != (const PPLine &other) const
{ return offset != other.offset; }
bool operator < (const PPLine &other) const
{ return offset < other.offset; }
};
unsigned findLineNumber(unsigned offset) const;
unsigned findColumnNumber(unsigned offset, unsigned lineNumber) const;
PPLine findPreprocessorLine(unsigned offset) const;
void showErrorLine(unsigned index, unsigned column, FILE *out);
Control *_control;
2009-12-01 11:33:13 +01:00
const StringLiteral *_fileId;
2008-12-02 12:01:29 +01:00
const char *_firstSourceChar;
const char *_lastSourceChar;
std::vector<Token> *_tokens;
std::vector<Token> *_comments;
2008-12-02 12:01:29 +01:00
std::vector<unsigned> _lineOffsets;
std::vector<PPLine> _ppLines;
C++: Core changes in preprocessing Summary of most relevant items: - Preprocessor output format change. No more gen true/false. Instead a more intuitive and natural expansion (like from a real compiler) is performed directly corresponding to the macro invocation. Notice that information about the generated tokens is not lost, because it's now embedded in the expansion section header (in terms of lines and columns as explained in the code). In addition the location on where the macro expansion happens is also documented for future use. - Fix line control directives and associated token line numbers. This was not detected in tests cases because some of them were actually wrong: Within expansions the line information was being considered as originally computed in the macro definition, while the desired and expected for Creator's reporting mechanism (just like regular compilers) is the line from the expanded version of the tokens. - Do not allow for eager expansion. This was previously being done inside define directives. However, it's not allowed and might lead to incorrect results, since the argument substitution should only happen upon the macro invocation (and following nested ones). At least GCC and clang are consistent with that. See test case tst_Preprocessor:dont_eagerly_expand for a detailed explanation. - Revive the 'expanded' token flag. This is used to mark every token that originates from a macro expansion. Notice, however, that expanded tokens are not necessarily generated tokens (although every generated token is a expanded token). Expanded tokens that are not generated are those which are still considered by our code model features, since they are visible on the editor. The translation unit is smart enough to calculate line/column position for such tokens based on the information from the expansion section header. - How expansions are tracked has also changed. Now, we simply add two surrounding marker tokens to each "top-level" expansion sequence. There is an enumeration that control expansion states. Also, no "previous" token is kept around. - Preprocessor client methods suffered a change in signature so they now receive the line number of the action in question as a paramater. Previously such line could be retrieved by the client implementation by accessing the environment line. However, this is not reliable because we try to avoid synchronization of the output/environment lines in order to avoid unnecessary output, while expanding macros or handling preprocessor directives. - Although macros are not expanded during define directives (as mentioned above) the preprocessor client is now "notified" when it sees a macro. This is to allow usage tracking. - Other small stuff. This is all in one patch because the fixes are a consequence of the change in preprocessing control. Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
2012-06-20 15:22:02 +02:00
std::map<unsigned, std::pair<unsigned, unsigned> > _expandedLineColumn; // TODO: Replace this for a hash
2008-12-02 12:01:29 +01:00
MemoryPool *_pool;
AST *_ast;
2008-12-02 12:01:29 +01:00
TranslationUnit *_previousTranslationUnit;
struct Flags {
unsigned _tokenized: 1;
unsigned _parsed: 1;
unsigned _blockErrors: 1;
unsigned _skipFunctionBody: 1;
unsigned _qtMocRunEnabled: 1;
2010-03-24 12:54:25 +01:00
unsigned _cxx0xEnabled: 1;
unsigned _objCEnabled: 1;
};
2008-12-02 12:01:29 +01:00
union {
unsigned _flags;
Flags f;
2008-12-02 12:01:29 +01:00
};
};
} // namespace CPlusPlus
2008-12-02 12:01:29 +01:00
#endif // CPLUSPLUS_TRANSLATIONUNIT_H