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(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(Ty);
26 
27   TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation());
28   Expr *Result =
29       S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), 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(Ctx, (uint64_t)Ptr));
37 }
38 
39 Sema::DeclGroupPtrTy CreateDGPtrFrom(Sema &S, Decl *D) {
40   SmallVector<Decl *, 1> DeclsInGroup;
41   DeclsInGroup.push_back(D);
42   Sema::DeclGroupPtrTy DeclGroupPtr = S.BuildDeclaratorGroup(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.TUScope);
54   else {
55     if (const auto *TD = dyn_cast<clang::TagDecl>(Within);
56         TD && !TD->getDefinition())
57       // No definition, no lookup result.
58       return nullptr;
59 
60     S.LookupQualifiedName(R, const_cast<DeclContext *>(Within));
61   }
62 
63   if (R.empty())
64     return nullptr;
65 
66   R.resolveKind();
67 
68   return dyn_cast<NamespaceDecl>(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                  Sema::ForVisibleRedeclaration);
76 
77   R.suppressDiagnostics();
78 
79   if (!Within)
80     S.LookupName(R, S.TUScope);
81   else {
82     const DeclContext *PrimaryWithin = nullptr;
83     if (const auto *TD = dyn_cast<TagDecl>(Within))
84       PrimaryWithin = llvm::dyn_cast_or_null<DeclContext>(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, 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>(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