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