Changeset View
Changeset View
Standalone View
Standalone View
lib/Sema/SemaLookup.cpp
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <iterator> | #include <iterator> | ||||
#include <list> | #include <list> | ||||
#include <set> | #include <set> | ||||
#include <utility> | #include <utility> | ||||
#include <vector> | #include <vector> | ||||
#include "clang/Basic/OpenCLBuiltins.inc" | |||||
using namespace clang; | using namespace clang; | ||||
using namespace sema; | using namespace sema; | ||||
namespace { | namespace { | ||||
class UnqualUsingEntry { | class UnqualUsingEntry { | ||||
const DeclContext *Nominated; | const DeclContext *Nominated; | ||||
const DeclContext *CommonAncestor; | const DeclContext *CommonAncestor; | ||||
▲ Show 20 Lines • Show All 604 Lines • ▼ Show 20 Lines | |||||
LLVM_DUMP_METHOD void LookupResult::dump() { | LLVM_DUMP_METHOD void LookupResult::dump() { | ||||
llvm::errs() << "lookup results for " << getLookupName().getAsString() | llvm::errs() << "lookup results for " << getLookupName().getAsString() | ||||
<< ":\n"; | << ":\n"; | ||||
for (NamedDecl *D : *this) | for (NamedDecl *D : *this) | ||||
D->dump(); | D->dump(); | ||||
} | } | ||||
// TODO: Auto-generate this from tablegen | |||||
static QualType OCL2Qual(ASTContext &Context, OpenCLType Ty) { | |||||
QualType RT = Context.VoidTy; | |||||
switch (Ty.ID) { | |||||
case OCLT_size_t: | |||||
RT = Context.getSizeType(); | |||||
break; | |||||
case OCLT_int: | |||||
RT = Context.IntTy; | |||||
break; | |||||
case OCLT_uint: | |||||
RT = Context.UnsignedIntTy; | |||||
break; | |||||
case OCLT_char: | |||||
RT = Context.CharTy; | |||||
break; | |||||
case OCLT_uchar: | |||||
RT = Context.UnsignedCharTy; | |||||
break; | |||||
case OCLT_short: | |||||
RT = Context.ShortTy; | |||||
break; | |||||
case OCLT_ushort: | |||||
RT = Context.UnsignedShortTy; | |||||
break; | |||||
case OCLT_long: | |||||
RT = Context.LongTy; | |||||
break; | |||||
case OCLT_ulong: | |||||
RT = Context.UnsignedLongTy; | |||||
break; | |||||
case OCLT_float: | |||||
RT = Context.FloatTy; | |||||
break; | |||||
case OCLT_double: | |||||
RT = Context.DoubleTy; | |||||
break; | |||||
case OCLT_image2d_ro_t: | |||||
RT = Context.OCLImage2dROTy; | |||||
break; | |||||
case OCLT_image2d_wo_t: | |||||
RT = Context.OCLImage2dWOTy; | |||||
break; | |||||
case OCLT_void_t: | |||||
RT = Context.VoidTy; | |||||
break; | |||||
default: | |||||
assert(0 && "unexpected type!"); | |||||
break; | |||||
} | |||||
if (Ty.VectorWidth > 0) | |||||
RT = Context.getExtVectorType(RT, Ty.VectorWidth); | |||||
if (Ty.isPointer != 0) { | |||||
RT = Context.getAddrSpaceQualType(RT, Ty.AS); | |||||
RT = Context.getPointerType(RT); | |||||
} | |||||
return RT; | |||||
} | |||||
static void InsertBuiltinDeclarations(Sema &S, LookupResult &LR, | |||||
IdentifierInfo *II, | |||||
unsigned Index, unsigned Len) { | |||||
for (unsigned i = 0; i < Len; ++i) { | |||||
OpenCLBuiltinDecl &Decl = OpenCLBuiltins[Index - 1 + i]; | |||||
ASTContext &Context = S.Context; | |||||
// Ignore this BIF if the the version is incorrect. | |||||
if (Context.getLangOpts().OpenCLVersion < Decl.Version) | |||||
continue; | |||||
FunctionProtoType::ExtProtoInfo PI; | |||||
PI.Variadic = false; | |||||
QualType RT = OCL2Qual(Context, OpenCLArgTypes[Decl.ArgTableIndex]); | |||||
SmallVector<QualType, 5> ArgTypes; | |||||
for (unsigned i = 1; i < Decl.NumArgs; i++) { | |||||
QualType Ty = OCL2Qual(Context, OpenCLArgTypes[Decl.ArgTableIndex + i]); | |||||
ArgTypes.push_back(Ty); | |||||
} | |||||
QualType R = Context.getFunctionType(RT, ArgTypes, PI); | |||||
SourceLocation Loc = LR.getNameLoc(); | |||||
// TODO: This part is taken from Sema::LazilyCreateBuiltin, maybe refactor it. | |||||
DeclContext *Parent = Context.getTranslationUnitDecl(); | |||||
FunctionDecl *New = FunctionDecl::Create(Context, | |||||
Parent, | |||||
Loc, Loc, II, R, /*TInfo=*/nullptr, | |||||
SC_Extern, | |||||
false, | |||||
R->isFunctionProtoType()); | |||||
New->setImplicit(); | |||||
// Create Decl objects for each parameter, adding them to the | |||||
// FunctionDecl. | |||||
if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) { | |||||
SmallVector<ParmVarDecl*, 16> Params; | |||||
for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { | |||||
ParmVarDecl *parm = | |||||
ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), | |||||
nullptr, FT->getParamType(i), /*TInfo=*/nullptr, | |||||
SC_None, nullptr); | |||||
parm->setScopeInfo(0, i); | |||||
Params.push_back(parm); | |||||
} | |||||
New->setParams(Params); | |||||
} | |||||
New->addAttr(OverloadableAttr::CreateImplicit(Context)); | |||||
if (strlen(Decl.Extension)) | |||||
S.setOpenCLExtensionForDecl(New, Decl.Extension); | |||||
LR.addDecl(New); | |||||
} | |||||
// If we added overloads, need to resolve the lookup result. | |||||
if (Len > 1) | |||||
LR.resolveKind(); | |||||
} | |||||
/// Lookup a builtin function, when name lookup would otherwise | /// Lookup a builtin function, when name lookup would otherwise | ||||
/// fail. | /// fail. | ||||
static bool LookupBuiltin(Sema &S, LookupResult &R) { | static bool LookupBuiltin(Sema &S, LookupResult &R) { | ||||
Sema::LookupNameKind NameKind = R.getLookupKind(); | Sema::LookupNameKind NameKind = R.getLookupKind(); | ||||
// If we didn't find a use of this identifier, and if the identifier | // If we didn't find a use of this identifier, and if the identifier | ||||
// corresponds to a compiler builtin, create the decl object for the builtin | // corresponds to a compiler builtin, create the decl object for the builtin | ||||
// now, injecting it into translation unit scope, and return it. | // now, injecting it into translation unit scope, and return it. | ||||
if (NameKind == Sema::LookupOrdinaryName || | if (NameKind == Sema::LookupOrdinaryName || | ||||
NameKind == Sema::LookupRedeclarationWithLinkage) { | NameKind == Sema::LookupRedeclarationWithLinkage) { | ||||
IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo(); | IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo(); | ||||
if (II) { | if (II) { | ||||
if (S.getLangOpts().CPlusPlus && NameKind == Sema::LookupOrdinaryName) { | if (S.getLangOpts().CPlusPlus && NameKind == Sema::LookupOrdinaryName) { | ||||
if (II == S.getASTContext().getMakeIntegerSeqName()) { | if (II == S.getASTContext().getMakeIntegerSeqName()) { | ||||
R.addDecl(S.getASTContext().getMakeIntegerSeqDecl()); | R.addDecl(S.getASTContext().getMakeIntegerSeqDecl()); | ||||
return true; | return true; | ||||
} else if (II == S.getASTContext().getTypePackElementName()) { | } else if (II == S.getASTContext().getTypePackElementName()) { | ||||
R.addDecl(S.getASTContext().getTypePackElementDecl()); | R.addDecl(S.getASTContext().getTypePackElementDecl()); | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
// Check if this is an OpenCL Builtin, and if so, insert the declarations. | |||||
if (S.getLangOpts().OpenCL) { | |||||
auto Index = isOpenCLBuiltin(II->getName()); | |||||
if (Index.first) { | |||||
InsertBuiltinDeclarations(S, R, II, Index.first, Index.second); | |||||
return true; | |||||
} | |||||
} | |||||
// If this is a builtin on this (or all) targets, create the decl. | // If this is a builtin on this (or all) targets, create the decl. | ||||
if (unsigned BuiltinID = II->getBuiltinID()) { | if (unsigned BuiltinID = II->getBuiltinID()) { | ||||
// In C++ and OpenCL (spec v1.2 s6.9.f), we don't have any predefined | // In C++ and OpenCL (spec v1.2 s6.9.f), we don't have any predefined | ||||
// library functions like 'malloc'. Instead, we'll just error. | // library functions like 'malloc'. Instead, we'll just error. | ||||
if ((S.getLangOpts().CPlusPlus || S.getLangOpts().OpenCL) && | if ((S.getLangOpts().CPlusPlus || S.getLangOpts().OpenCL) && | ||||
S.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) | S.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 991 Lines • Show Last 20 Lines |