|
1 | 1 | #include "DefineFinder.h"
|
2 | 2 |
|
3 | 3 | #include <clang/Basic/IdentifierTable.h>
|
| 4 | +#include <clang/Lex/LiteralSupport.h> |
4 | 5 | #include <clang/Lex/MacroInfo.h>
|
5 | 6 |
|
6 |
| -DefineFinder::DefineFinder(IR &ir, const clang::CompilerInstance &compiler) |
7 |
| - : ir(ir), compiler(compiler) {} |
| 7 | +DefineFinder::DefineFinder(IR &ir, const clang::CompilerInstance &compiler, |
| 8 | + clang::Preprocessor &pp) |
| 9 | + : ir(ir), compiler(compiler), pp(pp) {} |
8 | 10 |
|
9 | 11 | void DefineFinder::MacroDefined(const clang::Token &MacroNameTok,
|
10 | 12 | const clang::MacroDirective *MD) {
|
@@ -38,14 +40,11 @@ void DefineFinder::MacroDefined(const clang::Token &MacroNameTok,
|
38 | 40 | /* might be converted directly to Scala code */
|
39 | 41 | std::string literal(finalToken->getLiteralData(),
|
40 | 42 | finalToken->getLength());
|
41 |
| - switch (finalToken->getKind()) { |
42 |
| - case clang::tok::numeric_constant: |
43 |
| - ir.addLiteralDefine(macroName, literal); |
44 |
| - break; |
45 |
| - case clang::tok::string_literal: |
| 43 | + if (finalToken->getKind() == clang::tok::numeric_constant) { |
| 44 | + addNumericConstantDefine(macroName, literal, finalToken); |
| 45 | + } else if (finalToken->getKind() == clang::tok::string_literal) { |
46 | 46 | ir.addLiteralDefine(macroName, "c" + literal, "native.CString");
|
47 |
| - break; |
48 |
| - default: |
| 47 | + } else { |
49 | 48 | llvm::errs() << "Warning: type of literal "
|
50 | 49 | << finalToken->getName() << " is unsupported\n";
|
51 | 50 | llvm::errs().flush();
|
@@ -75,3 +74,28 @@ void DefineFinder::MacroUndefined(const clang::Token &MacroNameTok,
|
75 | 74 | ir.removeDefine(macroName);
|
76 | 75 | }
|
77 | 76 | }
|
| 77 | + |
| 78 | +void DefineFinder::addNumericConstantDefine(const std::string ¯oName, |
| 79 | + const std::string &literal, |
| 80 | + const clang::Token *finalToken) { |
| 81 | + clang::NumericLiteralParser parser(literal, finalToken->getLocation(), pp); |
| 82 | + std::string type; |
| 83 | + if (parser.isIntegerLiteral()) { |
| 84 | + if (parser.isLongLong) { |
| 85 | + return; |
| 86 | + } |
| 87 | + if (parser.isLong) { |
| 88 | + type = "native.CLong"; |
| 89 | + } else { |
| 90 | + type = "native.CInt"; |
| 91 | + } |
| 92 | + } else { |
| 93 | + if (parser.isFloat) { |
| 94 | + type = "native.CFloat"; |
| 95 | + // TODO: distinguish between float and double |
| 96 | + } |
| 97 | + } |
| 98 | + if (!type.empty()) { |
| 99 | + ir.addLiteralDefine(macroName, literal, type); |
| 100 | + } |
| 101 | +} |
0 commit comments