1a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===//
2a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//
3a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//                     The LLVM Compiler Infrastructure
4a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//
5a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner// This file is distributed under the University of Illinois Open Source
6a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner// License. See LICENSE.TXT for details.
7a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//
8a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//===----------------------------------------------------------------------===//
9a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//
10321f278db3405268e8644eb75f4fcf8900e0d09cArgyrios Kyrtzidis// This file defines the IdentifierResolver class, which is used for lexical
112def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor// scoped lookup, based on declaration names.
12a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//
13a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner//===----------------------------------------------------------------------===//
14a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
15a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
16a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
17a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
1800bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis#include "clang/Basic/IdentifierTable.h"
198fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallVector.h"
2000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
21a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattnernamespace clang {
22a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
237cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCallclass ASTContext;
247cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCallclass Decl;
257cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCallclass DeclContext;
267cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCallclass DeclarationName;
27eee242ff426bf79149f221798966e58688383c1eDouglas Gregorclass ExternalPreprocessorSource;
287cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCallclass NamedDecl;
29eee242ff426bf79149f221798966e58688383c1eDouglas Gregorclass Preprocessor;
307cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCallclass Scope;
31eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
322def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor/// IdentifierResolver - Keeps track of shadowed decls on enclosing
332def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor/// scopes.  It manages the shadowing chains of declaration names and
34fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner/// implements efficient decl lookup based on a declaration name.
35a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattnerclass IdentifierResolver {
3600bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
372def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// IdDeclInfo - Keeps track of information about decls associated
382def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// to a particular declaration name. IdDeclInfos are lazily
392def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// constructed and assigned to a declaration name the first time a
402def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// decl with that declaration name is shadowed in some scope.
4100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  class IdDeclInfo {
4200bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  public:
43686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    typedef SmallVector<NamedDecl*, 2> DeclsTy;
4400bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
4500bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
4600bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    inline DeclsTy::iterator decls_end() { return Decls.end(); }
4700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
48074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    void AddDecl(NamedDecl *D) { Decls.push_back(D); }
4900bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
5000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    /// RemoveDecl - Remove the decl from the scope chain.
5100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    /// The decl must already be part of the decl chain.
5281bebb1e2e6bb05e360f36da098dc7016e8f654bArgyrios Kyrtzidis    void RemoveDecl(NamedDecl *D);
5300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
547cbc558ffda5877ec4d2e432534e3d3d4ac10050Douglas Gregor    /// \brief Insert the given declaration at the given position in the list.
557cbc558ffda5877ec4d2e432534e3d3d4ac10050Douglas Gregor    void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
567cbc558ffda5877ec4d2e432534e3d3d4ac10050Douglas Gregor      Decls.insert(Pos, D);
577cbc558ffda5877ec4d2e432534e3d3d4ac10050Douglas Gregor    }
587cbc558ffda5877ec4d2e432534e3d3d4ac10050Douglas Gregor
5900bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  private:
6000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    DeclsTy Decls;
6100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  };
6200bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
6390eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidispublic:
6490eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis
652def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// iterator - Iterate over the decls of a specified declaration name.
6690eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis  /// It will walk or not the parent declaration contexts depending on how
6790eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis  /// it was instantiated.
6890eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis  class iterator {
696ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor  public:
706ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor    typedef NamedDecl *             value_type;
716ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor    typedef NamedDecl *             reference;
726ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor    typedef NamedDecl *             pointer;
736ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor    typedef std::input_iterator_tag iterator_category;
746ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor    typedef std::ptrdiff_t          difference_type;
756ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor
7690eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// Ptr - There are 3 forms that 'Ptr' represents:
7790eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
7890eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
7990eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    ///    same declaration context. (Ptr & 0x3 == 0x1)
8090eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
8190eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    ///    declaration contexts too. (Ptr & 0x3 == 0x3)
8200bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    uintptr_t Ptr;
8390eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    typedef IdDeclInfo::DeclsTy::iterator BaseIter;
8400bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
8590eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// A single NamedDecl. (Ptr & 0x1 == 0)
8690eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    iterator(NamedDecl *D) {
8700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis      Ptr = reinterpret_cast<uintptr_t>(D);
8890eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis      assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
8900bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    }
9090eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
9190eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    /// contexts depending on 'LookInParentCtx'.
924c921ae760cbdd9270c16d48417d7d527eb0ceb8Douglas Gregor    iterator(BaseIter I) {
9390eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis      Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
9400bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    }
9500bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
9600bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    bool isIterator() const { return (Ptr & 0x1); }
9700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
9890eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    BaseIter getIterator() const {
9990eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis      assert(isIterator() && "Ptr not an iterator!");
10090eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis      return reinterpret_cast<BaseIter>(Ptr & ~0x3);
10190eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    }
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    friend class IdentifierResolver;
1047cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall
1057cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall    void incrementSlowCase();
10600bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  public:
107b53c784cf6cef2673c481879b44edb3eede8bc2eArgyrios Kyrtzidis    iterator() : Ptr(0) {}
108b53c784cf6cef2673c481879b44edb3eede8bc2eArgyrios Kyrtzidis
10900bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    NamedDecl *operator*() const {
11000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis      if (isIterator())
11100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis        return *getIterator();
11200bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis      else
11300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis        return reinterpret_cast<NamedDecl*>(Ptr);
11400bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    }
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11690eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    bool operator==(const iterator &RHS) const {
11700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis      return Ptr == RHS.Ptr;
11800bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    }
11990eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    bool operator!=(const iterator &RHS) const {
12000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis      return Ptr != RHS.Ptr;
12100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    }
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    // Preincrement.
12490eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    iterator& operator++() {
12590eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis      if (!isIterator()) // common case.
12600bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis        Ptr = 0;
1277cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall      else
1287cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall        incrementSlowCase();
12900bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis      return *this;
13000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    }
13100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
132eb11cd078ba8682bbb9b082f8f6ead8be5c98581Douglas Gregor    uintptr_t getAsOpaqueValue() const { return Ptr; }
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
134eb11cd078ba8682bbb9b082f8f6ead8be5c98581Douglas Gregor    static iterator getFromOpaqueValue(uintptr_t P) {
1354c921ae760cbdd9270c16d48417d7d527eb0ceb8Douglas Gregor      iterator Result;
136eb11cd078ba8682bbb9b082f8f6ead8be5c98581Douglas Gregor      Result.Ptr = P;
137eb11cd078ba8682bbb9b082f8f6ead8be5c98581Douglas Gregor      return Result;
138eb11cd078ba8682bbb9b082f8f6ead8be5c98581Douglas Gregor    }
13990eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis  };
14000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
1414c921ae760cbdd9270c16d48417d7d527eb0ceb8Douglas Gregor  /// begin - Returns an iterator for decls with the name 'Name'.
142eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  iterator begin(DeclarationName Name);
14300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
14490eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis  /// end - Returns an iterator that has 'finished'.
145eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  iterator end() {
14690eb539bc3121bdc0e867ab1cd6bdca3b36d961eArgyrios Kyrtzidis    return iterator();
14700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  }
14800bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
149e29f0a47ed56645d6a02d49e0fa9f4b9383611ddArgyrios Kyrtzidis  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
150e29f0a47ed56645d6a02d49e0fa9f4b9383611ddArgyrios Kyrtzidis  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
151e29f0a47ed56645d6a02d49e0fa9f4b9383611ddArgyrios Kyrtzidis  /// true if 'D' belongs to the given declaration context.
152cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  ///
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param AllowInlineNamespace If \c true, we are checking whether a prior
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///        declaration is in scope in a declaration that requires a prior
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///        declaration (because it is either explicitly qualified or is a
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///        template instantiation or specialization). In this case, a
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///        declaration is in scope if it's in the inline namespace set of the
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///        context.
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                     bool AllowInlineNamespace = false) const;
161a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
162321f278db3405268e8644eb75f4fcf8900e0d09cArgyrios Kyrtzidis  /// AddDecl - Link the decl to its shadowed decl chain.
16300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  void AddDecl(NamedDecl *D);
164a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
165321f278db3405268e8644eb75f4fcf8900e0d09cArgyrios Kyrtzidis  /// RemoveDecl - Unlink the decl from its shadowed decl chain.
166a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner  /// The decl must already be part of the decl chain.
167a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner  void RemoveDecl(NamedDecl *D);
168a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
169250e7a74d5a23db5bd7202ecb0bb4a8fef6016b4Douglas Gregor  /// \brief Insert the given declaration after the given iterator
170250e7a74d5a23db5bd7202ecb0bb4a8fef6016b4Douglas Gregor  /// position.
171250e7a74d5a23db5bd7202ecb0bb4a8fef6016b4Douglas Gregor  void InsertDeclAfter(iterator Pos, NamedDecl *D);
1727cbc558ffda5877ec4d2e432534e3d3d4ac10050Douglas Gregor
173eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \brief Try to add the given declaration to the top level scope, if it
174eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// (or a redeclaration of it) hasn't already been added.
175668c1a4fdcc56bdd050256b1688e116fe84b72dbDouglas Gregor  ///
176eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \param D The externally-produced declaration to add.
177eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  ///
178eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \param Name The name of the externally-produced declaration.
179eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  ///
180eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  /// \returns true if the declaration was added, false otherwise.
181eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
182eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
183eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  explicit IdentifierResolver(Preprocessor &PP);
18400bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  ~IdentifierResolver();
185a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
186a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattnerprivate:
187eb7c388bc7ce19fffb8b4b440cee0173297e8490Argyrios Kyrtzidis  const LangOptions &LangOpt;
188eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  Preprocessor &PP;
189eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
19000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  class IdDeclInfoMap;
19100bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  IdDeclInfoMap *IdDeclInfos;
19200bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
193eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  void updatingIdentifier(IdentifierInfo &II);
194eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  void readingIdentifier(IdentifierInfo &II);
195eee242ff426bf79149f221798966e58688383c1eDouglas Gregor
1962def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// FETokenInfo contains a Decl pointer if lower bit == 0.
19700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  static inline bool isDeclPtr(void *Ptr) {
19800bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
19900bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  }
20000bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis
2012def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor  /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
20200bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
20300bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
20400bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis          && "Ptr not a IdDeclInfo* !");
20500bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis    return reinterpret_cast<IdDeclInfo*>(
20600bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis                    reinterpret_cast<uintptr_t>(Ptr) & ~0x1
20700bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis                                                            );
20800bc645d154f8f30bfbfb2fe508caf087793157cArgyrios Kyrtzidis  }
209a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner};
210a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
211a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner} // end namespace clang
212a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner
213a2f42b1d18db7a6e05314b04532a6643e1ffba0fChris Lattner#endif
214