Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Tooling/Transformer/SourceCode.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- SourceCode.cpp - Source code manipulation routines -----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file provides functions that simplify extraction of source code.
10
//
11
//===----------------------------------------------------------------------===//
12
#include "clang/Tooling/Transformer/SourceCode.h"
13
#include "clang/Lex/Lexer.h"
14
#include "llvm/Support/Errc.h"
15
16
using namespace clang;
17
18
using llvm::errc;
19
using llvm::StringError;
20
21
StringRef clang::tooling::getText(CharSourceRange Range,
22
114
                                  const ASTContext &Context) {
23
114
  return Lexer::getSourceText(Range, Context.getSourceManager(),
24
114
                              Context.getLangOpts());
25
114
}
26
27
CharSourceRange clang::tooling::maybeExtendRange(CharSourceRange Range,
28
                                                 tok::TokenKind Next,
29
35
                                                 ASTContext &Context) {
30
35
  Optional<Token> Tok = Lexer::findNextToken(
31
35
      Range.getEnd(), Context.getSourceManager(), Context.getLangOpts());
32
35
  if (!Tok || 
!Tok->is(Next)34
)
33
17
    return Range;
34
18
  return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation());
35
18
}
36
37
llvm::Error clang::tooling::validateEditRange(const CharSourceRange &Range,
38
62
                                              const SourceManager &SM) {
39
62
  if (Range.isInvalid())
40
6
    return llvm::make_error<StringError>(errc::invalid_argument,
41
6
                                         "Invalid range");
42
56
43
56
  if (Range.getBegin().isMacroID() || 
Range.getEnd().isMacroID()52
)
44
4
    return llvm::make_error<StringError>(
45
4
        errc::invalid_argument, "Range starts or ends in a macro expansion");
46
52
47
52
  if (SM.isInSystemHeader(Range.getBegin()) ||
48
52
      SM.isInSystemHeader(Range.getEnd()))
49
0
    return llvm::make_error<StringError>(errc::invalid_argument,
50
0
                                         "Range is in system header");
51
52
52
52
  std::pair<FileID, unsigned> BeginInfo = SM.getDecomposedLoc(Range.getBegin());
53
52
  std::pair<FileID, unsigned> EndInfo = SM.getDecomposedLoc(Range.getEnd());
54
52
  if (BeginInfo.first != EndInfo.first)
55
0
    return llvm::make_error<StringError>(
56
0
        errc::invalid_argument, "Range begins and ends in different files");
57
52
58
52
  if (BeginInfo.second > EndInfo.second)
59
1
    return llvm::make_error<StringError>(
60
1
        errc::invalid_argument, "Range's begin is past its end");
61
51
62
51
  return llvm::Error::success();
63
51
}
64
65
llvm::Optional<CharSourceRange>
66
clang::tooling::getRangeForEdit(const CharSourceRange &EditRange,
67
                                const SourceManager &SM,
68
49
                                const LangOptions &LangOpts) {
69
49
  // FIXME: makeFileCharRange() has the disadvantage of stripping off "identity"
70
49
  // macros. For example, if we're looking to rewrite the int literal 3 to 6,
71
49
  // and we have the following definition:
72
49
  //    #define DO_NOTHING(x) x
73
49
  // then
74
49
  //    foo(DO_NOTHING(3))
75
49
  // will be rewritten to
76
49
  //    foo(6)
77
49
  // rather than the arguably better
78
49
  //    foo(DO_NOTHING(6))
79
49
  // Decide whether the current behavior is desirable and modify if not.
80
49
  CharSourceRange Range = Lexer::makeFileCharRange(EditRange, SM, LangOpts);
81
49
  bool IsInvalid = llvm::errorToBool(validateEditRange(Range, SM));
82
49
  if (IsInvalid)
83
5
    return llvm::None;
84
44
  return Range;
85
44
86
44
}