TranslationUnit.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright (c) 2008 Roberto Raggi <[email protected]>
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. #ifndef CPLUSPLUS_TRANSLATIONUNIT_H
  21. #define CPLUSPLUS_TRANSLATIONUNIT_H
  22. #include "CPlusPlusForwardDeclarations.h"
  23. #include "ASTfwd.h"
  24. #include "Token.h"
  25. #include "DiagnosticClient.h"
  26. #include <cstdio>
  27. #include <vector>
  28. #if !(__cplusplus > 199711L || __GXX_EXPERIMENTAL_CXX0X__ || _MSC_VER >= 1600 || defined( _LIBCPP_VERSION )) \
  29. || (defined(__GNUC_LIBSTD__) && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402))
  30. #define USE_TR1
  31. #endif
  32. #if defined(_MSC_VER) && _MSC_VER < 1600
  33. # include <map>
  34. #elif defined(USE_TR1)
  35. # include <tr1/unordered_map>
  36. #else
  37. # include <unordered_map>
  38. #endif
  39. namespace CPlusPlus {
  40. class CPLUSPLUS_EXPORT TranslationUnit
  41. {
  42. TranslationUnit(const TranslationUnit &other);
  43. void operator =(const TranslationUnit &other);
  44. public:
  45. TranslationUnit(Control *control, const StringLiteral *fileId);
  46. ~TranslationUnit();
  47. Control *control() const;
  48. const StringLiteral *fileId() const;
  49. const char *fileName() const;
  50. unsigned fileNameLength() const;
  51. const char *firstSourceChar() const;
  52. const char *lastSourceChar() const;
  53. unsigned sourceLength() const;
  54. void setSource(const char *source, unsigned size);
  55. unsigned tokenCount() const { return _tokens ? unsigned(_tokens->size()) : unsigned(0); }
  56. const Token &tokenAt(unsigned index) const
  57. { return _tokens && index < tokenCount() ? (*_tokens)[index] : nullToken; }
  58. Kind tokenKind(unsigned index) const { return tokenAt(index).kind(); }
  59. const char *spell(unsigned index) const;
  60. unsigned commentCount() const;
  61. const Token &commentAt(unsigned index) const;
  62. unsigned matchingBrace(unsigned index) const;
  63. const Identifier *identifier(unsigned index) const;
  64. const Literal *literal(unsigned index) const;
  65. const StringLiteral *stringLiteral(unsigned index) const;
  66. const NumericLiteral *numericLiteral(unsigned index) const;
  67. MemoryPool *memoryPool() const;
  68. AST *ast() const;
  69. bool blockErrors() const { return f._blockErrors; }
  70. bool blockErrors(bool block)
  71. {
  72. const bool previous = f._blockErrors;
  73. f._blockErrors = block;
  74. return previous;
  75. }
  76. void warning(unsigned index, const char *fmt, ...);
  77. void error(unsigned index, const char *fmt, ...);
  78. void fatal(unsigned index, const char *fmt, ...);
  79. void message(DiagnosticClient::Level level, unsigned index,
  80. const char *format, va_list ap);
  81. bool isTokenized() const;
  82. void tokenize();
  83. bool skipFunctionBody() const;
  84. void setSkipFunctionBody(bool skipFunctionBody);
  85. bool isParsed() const;
  86. enum ParseMode {
  87. ParseTranlationUnit,
  88. ParseDeclaration,
  89. ParseExpression,
  90. ParseDeclarator,
  91. ParseStatement
  92. };
  93. bool parse(ParseMode mode = ParseTranlationUnit);
  94. void resetAST();
  95. void release();
  96. void getTokenStartPosition(unsigned index, unsigned *line,
  97. unsigned *column = 0,
  98. const StringLiteral **fileName = 0) const;
  99. void getTokenEndPosition(unsigned index, unsigned *line,
  100. unsigned *column = 0,
  101. const StringLiteral **fileName = 0) const;
  102. void getPosition(unsigned utf16charOffset,
  103. unsigned *line,
  104. unsigned *column = 0,
  105. const StringLiteral **fileName = 0) const;
  106. void getTokenPosition(unsigned index,
  107. unsigned *line,
  108. unsigned *column = 0,
  109. const StringLiteral **fileName = 0) const;
  110. void pushLineOffset(unsigned offset);
  111. void pushPreprocessorLine(unsigned utf16charOffset,
  112. unsigned line,
  113. const StringLiteral *fileName);
  114. unsigned findPreviousLineOffset(unsigned tokenIndex) const;
  115. bool maybeSplitGreaterGreaterToken(unsigned tokenIndex);
  116. LanguageFeatures languageFeatures() const { return _languageFeatures; }
  117. void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; }
  118. private:
  119. struct PPLine {
  120. unsigned utf16charOffset;
  121. unsigned line;
  122. const StringLiteral *fileName;
  123. PPLine(unsigned utf16charOffset = 0,
  124. unsigned line = 0,
  125. const StringLiteral *fileName = 0)
  126. : utf16charOffset(utf16charOffset), line(line), fileName(fileName)
  127. { }
  128. bool operator == (const PPLine &other) const
  129. { return utf16charOffset == other.utf16charOffset; }
  130. bool operator != (const PPLine &other) const
  131. { return utf16charOffset != other.utf16charOffset; }
  132. bool operator < (const PPLine &other) const
  133. { return utf16charOffset < other.utf16charOffset; }
  134. };
  135. void releaseTokensAndComments();
  136. unsigned findLineNumber(unsigned utf16charOffset) const;
  137. unsigned findColumnNumber(unsigned utf16CharOffset, unsigned lineNumber) const;
  138. PPLine findPreprocessorLine(unsigned utf16charOffset) const;
  139. void showErrorLine(unsigned index, unsigned column, FILE *out);
  140. static const Token nullToken;
  141. Control *_control;
  142. const StringLiteral *_fileId;
  143. const char *_firstSourceChar;
  144. const char *_lastSourceChar;
  145. std::vector<Token> *_tokens;
  146. std::vector<Token> *_comments;
  147. std::vector<unsigned> _lineOffsets;
  148. std::vector<PPLine> _ppLines;
  149. #if defined(_MSC_VER) && _MSC_VER < 1600
  150. // MSVC2008 and earlier do not implement TR1.
  151. typedef std::map<unsigned, std::pair<unsigned, unsigned> > TokenLineColumn;
  152. #elif defined(USE_TR1)
  153. typedef std::tr1::unordered_map<unsigned, std::pair<unsigned, unsigned> > TokenLineColumn;
  154. #else
  155. typedef std::unordered_map<unsigned, std::pair<unsigned, unsigned> > TokenLineColumn;
  156. #endif
  157. TokenLineColumn _expandedLineColumn;
  158. MemoryPool *_pool;
  159. AST *_ast;
  160. TranslationUnit *_previousTranslationUnit;
  161. struct Flags {
  162. unsigned _tokenized: 1;
  163. unsigned _parsed: 1;
  164. unsigned _blockErrors: 1;
  165. unsigned _skipFunctionBody: 1;
  166. };
  167. union {
  168. unsigned _flags;
  169. Flags f;
  170. };
  171. LanguageFeatures _languageFeatures;
  172. };
  173. } // namespace CPlusPlus
  174. #endif // CPLUSPLUS_TRANSLATIONUNIT_H