1 //===--- CurrentSourceLocExprScope.h ----------------------------*- 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 defines types used to track the current context needed to evaluate
10 //  a SourceLocExpr.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
15 #define LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
16 
17 #include <cassert>
18 
19 namespace clang {
20 class Expr;
21 
22 /// Represents the current source location and context used to determine the
23 /// value of the source location builtins (ex. __builtin_LINE), including the
24 /// context of default argument and default initializer expressions.
25 class CurrentSourceLocExprScope {
26   /// The CXXDefaultArgExpr or CXXDefaultInitExpr we're currently evaluating.
27   const Expr *DefaultExpr = nullptr;
28 
29 public:
30   /// A RAII style scope guard used for tracking the current source
31   /// location and context as used by the source location builtins
32   /// (ex. __builtin_LINE).
33   class SourceLocExprScopeGuard;
34 
35   const Expr *getDefaultExpr() const { return DefaultExpr; }
36 
37   explicit CurrentSourceLocExprScope() = default;
38 
39 private:
40   explicit CurrentSourceLocExprScope(const Expr *DefaultExpr)
41       : DefaultExpr(DefaultExpr) {}
42 
43   CurrentSourceLocExprScope(CurrentSourceLocExprScope const &) = default;
44   CurrentSourceLocExprScope &
45   operator=(CurrentSourceLocExprScope const &) = default;
46 };
47 
48 class CurrentSourceLocExprScope::SourceLocExprScopeGuard {
49 public:
50   SourceLocExprScopeGuard(const Expr *DefaultExpr,
51                           CurrentSourceLocExprScope &Current)
52       : Current(Current), OldVal(Current), Enable(false) {
53     assert(DefaultExpr && "the new scope should not be empty");
54     if ((Enable = (Current.getDefaultExpr() == nullptr)))
55       Current = CurrentSourceLocExprScope(DefaultExpr);
56   }
57 
58   ~SourceLocExprScopeGuard() {
59     if (Enable)
60       Current = OldVal;
61   }
62 
63 private:
64   SourceLocExprScopeGuard(SourceLocExprScopeGuard const &) = delete;
65   SourceLocExprScopeGuard &operator=(SourceLocExprScopeGuard const &) = delete;
66 
67   CurrentSourceLocExprScope &Current;
68   CurrentSourceLocExprScope OldVal;
69   bool Enable;
70 };
71 
72 } // end namespace clang
73 
74 #endif // LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
75