1 | //===--- InterpreterUtils.cpp - Incremental Utils --------*- 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 implements some common utils used in the incremental library. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "InterpreterUtils.h" |
14 | |
15 | namespace clang { |
16 | |
17 | IntegerLiteral *IntegerLiteralExpr(ASTContext &C, uint64_t Val) { |
18 | return IntegerLiteral::Create(C, llvm::APSInt::getUnsigned(X: Val), |
19 | C.UnsignedLongLongTy, SourceLocation()); |
20 | } |
21 | |
22 | Expr *CStyleCastPtrExpr(Sema &S, QualType Ty, Expr *E) { |
23 | ASTContext &Ctx = S.getASTContext(); |
24 | if (!Ty->isPointerType()) |
25 | Ty = Ctx.getPointerType(T: Ty); |
26 | |
27 | TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(T: Ty, Loc: SourceLocation()); |
28 | Expr *Result = |
29 | S.BuildCStyleCastExpr(LParenLoc: SourceLocation(), Ty: TSI, RParenLoc: SourceLocation(), Op: E).get(); |
30 | assert(Result && "Cannot create CStyleCastPtrExpr" ); |
31 | return Result; |
32 | } |
33 | |
34 | Expr *CStyleCastPtrExpr(Sema &S, QualType Ty, uintptr_t Ptr) { |
35 | ASTContext &Ctx = S.getASTContext(); |
36 | return CStyleCastPtrExpr(S, Ty, IntegerLiteralExpr(C&: Ctx, Val: (uint64_t)Ptr)); |
37 | } |
38 | |
39 | Sema::DeclGroupPtrTy CreateDGPtrFrom(Sema &S, Decl *D) { |
40 | SmallVector<Decl *, 1> DeclsInGroup; |
41 | DeclsInGroup.push_back(Elt: D); |
42 | Sema::DeclGroupPtrTy DeclGroupPtr = S.BuildDeclaratorGroup(Group: DeclsInGroup); |
43 | return DeclGroupPtr; |
44 | } |
45 | |
46 | NamespaceDecl *LookupNamespace(Sema &S, llvm::StringRef Name, |
47 | const DeclContext *Within) { |
48 | DeclarationName DName = &S.Context.Idents.get(Name); |
49 | LookupResult R(S, DName, SourceLocation(), |
50 | Sema::LookupNestedNameSpecifierName); |
51 | R.suppressDiagnostics(); |
52 | if (!Within) |
53 | S.LookupName(R, S: S.TUScope); |
54 | else { |
55 | if (const auto *TD = dyn_cast<clang::TagDecl>(Val: Within); |
56 | TD && !TD->getDefinition()) |
57 | // No definition, no lookup result. |
58 | return nullptr; |
59 | |
60 | S.LookupQualifiedName(R, LookupCtx: const_cast<DeclContext *>(Within)); |
61 | } |
62 | |
63 | if (R.empty()) |
64 | return nullptr; |
65 | |
66 | R.resolveKind(); |
67 | |
68 | return dyn_cast<NamespaceDecl>(Val: R.getFoundDecl()); |
69 | } |
70 | |
71 | NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name, |
72 | const DeclContext *Within) { |
73 | DeclarationName DName = &S.Context.Idents.get(Name); |
74 | LookupResult R(S, DName, SourceLocation(), Sema::LookupOrdinaryName, |
75 | RedeclarationKind::ForVisibleRedeclaration); |
76 | |
77 | R.suppressDiagnostics(); |
78 | |
79 | if (!Within) |
80 | S.LookupName(R, S: S.TUScope); |
81 | else { |
82 | const DeclContext *PrimaryWithin = nullptr; |
83 | if (const auto *TD = dyn_cast<TagDecl>(Val: Within)) |
84 | PrimaryWithin = llvm::dyn_cast_or_null<DeclContext>(Val: TD->getDefinition()); |
85 | else |
86 | PrimaryWithin = Within->getPrimaryContext(); |
87 | |
88 | // No definition, no lookup result. |
89 | if (!PrimaryWithin) |
90 | return nullptr; |
91 | |
92 | S.LookupQualifiedName(R, LookupCtx: const_cast<DeclContext *>(PrimaryWithin)); |
93 | } |
94 | |
95 | if (R.empty()) |
96 | return nullptr; |
97 | R.resolveKind(); |
98 | |
99 | if (R.isSingleResult()) |
100 | return llvm::dyn_cast<NamedDecl>(Val: R.getFoundDecl()); |
101 | |
102 | return nullptr; |
103 | } |
104 | |
105 | std::string GetFullTypeName(ASTContext &Ctx, QualType QT) { |
106 | PrintingPolicy Policy(Ctx.getPrintingPolicy()); |
107 | Policy.SuppressScope = false; |
108 | Policy.AnonymousTagLocations = false; |
109 | return QT.getAsString(Policy); |
110 | } |
111 | } // namespace clang |
112 | |