diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp index 11693132de687..cae728815b412 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp @@ -13,6 +13,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/Lex/Preprocessor.h" namespace clang { @@ -109,6 +110,43 @@ Nullability getNullabilityAnnotation(QualType Type) { return Nullability::Unspecified; } +llvm::Optional<int> tryExpandAsInteger(StringRef Macro, + const Preprocessor &PP) { + const auto *MacroII = PP.getIdentifierInfo(Macro); + if (!MacroII) + return llvm::None; + const MacroInfo *MI = PP.getMacroInfo(MacroII); + if (!MI) + return llvm::None; + + // Filter out parens. + std::vector<Token> FilteredTokens; + FilteredTokens.reserve(MI->tokens().size()); + for (auto &T : MI->tokens()) + if (!T.isOneOf(tok::l_paren, tok::r_paren)) + FilteredTokens.push_back(T); + + // Parse an integer at the end of the macro definition. + const Token &T = FilteredTokens.back(); + // FIXME: EOF macro token coming from a PCH file on macOS while marked as + // literal, doesn't contain any literal data + if (!T.isLiteral() || !T.getLiteralData()) + return llvm::None; + StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); + llvm::APInt IntValue; + constexpr unsigned AutoSenseRadix = 0; + if (ValueStr.getAsInteger(AutoSenseRadix, IntValue)) + return llvm::None; + + // Parse an optional minus sign. + size_t Size = FilteredTokens.size(); + if (Size >= 2) { + if (FilteredTokens[Size - 2].is(tok::minus)) + IntValue = -IntValue; + } + + return IntValue.getSExtValue(); +} -} // end namespace ento -} // end namespace clang +} // namespace ento +} // namespace clang |