xref: /freebsd/contrib/llvm-project/clang/include/clang/Lex/ExternalPreprocessorSource.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- 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 the ExternalPreprocessorSource interface, which enables
10 //  construction of macro definitions from some external source.
11 //
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
14 #define LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
15 
16 #include <cassert>
17 #include <cstdint>
18 
19 namespace clang {
20 
21 class IdentifierInfo;
22 class Module;
23 
24 /// Abstract interface for external sources of preprocessor
25 /// information.
26 ///
27 /// This abstract class allows an external sources (such as the \c ASTReader)
28 /// to provide additional preprocessing information.
29 class ExternalPreprocessorSource {
30 public:
31   virtual ~ExternalPreprocessorSource();
32 
33   /// Read the set of macros defined by this external macro source.
34   virtual void ReadDefinedMacros() = 0;
35 
36   /// Update an out-of-date identifier.
37   virtual void updateOutOfDateIdentifier(const IdentifierInfo &II) = 0;
38 
39   /// Return the identifier associated with the given ID number.
40   ///
41   /// The ID 0 is associated with the NULL identifier.
42   virtual IdentifierInfo *GetIdentifier(uint64_t ID) = 0;
43 
44   /// Map a module ID to a module.
45   virtual Module *getModule(unsigned ModuleID) = 0;
46 };
47 
48 // Either a pointer to an IdentifierInfo of the controlling macro or the ID
49 // number of the controlling macro.
50 class LazyIdentifierInfoPtr {
51   // If the low bit is clear, a pointer to the IdentifierInfo. If the low
52   // bit is set, the upper 63 bits are the ID number.
53   mutable uint64_t Ptr = 0;
54 
55 public:
56   LazyIdentifierInfoPtr() = default;
57 
LazyIdentifierInfoPtr(const IdentifierInfo * Ptr)58   explicit LazyIdentifierInfoPtr(const IdentifierInfo *Ptr)
59       : Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
60 
LazyIdentifierInfoPtr(uint64_t ID)61   explicit LazyIdentifierInfoPtr(uint64_t ID) : Ptr((ID << 1) | 0x01) {
62     assert((ID << 1 >> 1) == ID && "ID must require < 63 bits");
63     if (ID == 0)
64       Ptr = 0;
65   }
66 
67   LazyIdentifierInfoPtr &operator=(const IdentifierInfo *Ptr) {
68     this->Ptr = reinterpret_cast<uint64_t>(Ptr);
69     return *this;
70   }
71 
72   LazyIdentifierInfoPtr &operator=(uint64_t ID) {
73     assert((ID << 1 >> 1) == ID && "IDs must require < 63 bits");
74     if (ID == 0)
75       Ptr = 0;
76     else
77       Ptr = (ID << 1) | 0x01;
78 
79     return *this;
80   }
81 
82   /// Whether this pointer is non-NULL.
83   ///
84   /// This operation does not require the AST node to be deserialized.
isValid()85   bool isValid() const { return Ptr != 0; }
86 
87   /// Whether this pointer is currently stored as ID.
isID()88   bool isID() const { return Ptr & 0x01; }
89 
getPtr()90   IdentifierInfo *getPtr() const {
91     assert(!isID());
92     return reinterpret_cast<IdentifierInfo *>(Ptr);
93   }
94 
getID()95   uint64_t getID() const {
96     assert(isID());
97     return Ptr >> 1;
98   }
99 };
100 }
101 
102 #endif
103