bool ClangASTImporter::RequireCompleteType(clang::QualType type) { if (type.isNull()) return false; if (const TagType *tag_type = type->getAs<TagType>()) { TagDecl *tag_decl = tag_type->getDecl(); if (tag_decl->getDefinition() || tag_decl->isBeingDefined()) return true; return CompleteTagDecl(tag_decl); } if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) { if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) return CompleteObjCInterfaceDecl(objc_interface_decl); else return false; } if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) { return RequireCompleteType(array_type->getElementType()); } if (const AtomicType *atomic_type = type->getAs<AtomicType>()) { return RequireCompleteType(atomic_type->getPointeeType()); } return true; }
/** * Reports mismatch between buffer type and mpi datatype. * @param callExpr */ void MPIBugReporter::reportTypeMismatch( const CallExpr *callExpr, const std::pair<size_t, size_t> &idxPair, clang::QualType bufferType, std::string mpiType) const { auto adc = analysisManager_.getAnalysisDeclContext(currentFunctionDecl_); PathDiagnosticLocation location = PathDiagnosticLocation::createBegin( callExpr, bugReporter_.getSourceManager(), adc); // deref buffer type while (bufferType->isPointerType()) { bufferType = bufferType->getPointeeType(); } // remove qualifiers bufferType = bufferType.getUnqualifiedType(); SourceRange callRange = callExpr->getCallee()->getSourceRange(); std::string bugType{"type mismatch"}; std::string errorText{"Buffer type '" + bufferType.getAsString() + +"' and specified MPI type '" + mpiType + "' do not match. "}; llvm::SmallVector<SourceRange, 3> sourceRanges; sourceRanges.push_back(callRange); sourceRanges.push_back(callExpr->getArg(idxPair.first)->getSourceRange()); sourceRanges.push_back(callExpr->getArg(idxPair.second)->getSourceRange()); bugReporter_.EmitBasicReport(adc->getDecl(), &checkerBase_, bugType, MPIError, errorText, location, sourceRanges); }
static void StreamArr(llvm::raw_ostream& o, const void* V, clang::QualType Ty, cling::Interpreter& interp) { clang::ASTContext& C = interp.getCI()->getASTContext(); const clang::ArrayType* ArrTy = Ty->getAsArrayTypeUnsafe(); clang::QualType ElementTy = ArrTy->getElementType(); if (ElementTy->isCharType()) StreamCharPtr(o, (const char*)V); else if (Ty->isConstantArrayType()) { // Stream a constant array by streaming up to 5 elements. const clang::ConstantArrayType* CArrTy = C.getAsConstantArrayType(Ty); const llvm::APInt& APSize = CArrTy->getSize(); size_t ElBytes = C.getTypeSize(ElementTy) / C.getCharWidth(); size_t Size = (size_t)APSize.getZExtValue(); o << "{ "; for (size_t i = 0; i < Size; ++i) { // Handle the case of constant size array of pointers. Eg. const char*[] if (ElementTy->isPointerType()) StreamValue(o, *(const char* const *)V + i * ElBytes, ElementTy, interp); else StreamValue(o, (const char*)V + i * ElBytes, ElementTy, interp); if (i + 1 < Size) { if (i == 4) { o << "..."; break; } else o << ", "; } } o << " }"; } else StreamPtr(o, V); }
bool WebCLRestrictor::handleParmVarDecl(clang::ParmVarDecl *decl) { const clang::TypeSourceInfo *info = decl->getTypeSourceInfo(); if (!info) { error(decl->getSourceRange().getBegin(), "Invalid parameter type.\n"); return true; } clang::SourceLocation typeLocation = info->getTypeLoc().getBeginLoc(); const clang::QualType qualType = info->getType(); const clang::Type *type = qualType.getTypePtrOrNull(); if (!info) { error(typeLocation, "Invalid parameter type.\n"); return true; } const clang::DeclContext *context = decl->getParentFunctionOrMethod(); if (!context) { error(typeLocation, "Invalid parameter context.\n"); return true; } clang::FunctionDecl *function = clang::FunctionDecl::castFromDeclContext(context); if (!function) { error(typeLocation, "Invalid parameter context.\n"); return true; } checkStructureParameter(function, typeLocation, type); check3dImageParameter(function, typeLocation, type); checkUnsupportedBuiltinParameter(function, typeLocation, qualType); return true; }
// A loose type equality check that disregards all sugar, qualification, looks // through pointers, etc. static bool roughlyEqual(clang::QualType left, clang::QualType right) { auto leftPointee = left->getPointeeType(); if (leftPointee != clang::QualType()) left = leftPointee; auto rightPointee = right->getPointeeType(); if (rightPointee != clang::QualType()) right = rightPointee; return left->getUnqualifiedDesugaredType() == right->getUnqualifiedDesugaredType(); }
// updates S.Ok; and, depending on Kind, possibly S.FnAccumulatorOk or S.FnOutConverterOk void RSExportReduce::checkVoidReturn(StateOfAnalyzeTranslationUnit &S, FnIdent Kind, clang::FunctionDecl *Fn) { slangAssert(Fn); const clang::QualType ReturnTy = Fn->getReturnType().getCanonicalType(); if (!ReturnTy->isVoidType()) { S.RSC.ReportError(Fn->getLocation(), "%0 must return void not '%1'") << S.DiagnosticDescription(getKey(Kind), Fn->getName()) << ReturnTy.getAsString(); notOk(S, Kind); } }
bool IsStructuralType(const clang::QualType& type, const clang::ASTContext *context) { // If it is struct, check if all fields are of structural type if (type.getCanonicalType().getTypePtr()->isStructureType()) { clang::RecordDecl* struct_decl = type.getCanonicalType().getTypePtr()->getAsStructureType()->getDecl(); for (const auto* field : struct_decl->fields()) { if (!IsStructuralType(field->getType(),context)) return false; } return true; } else { // Else check if it is of integral type return type.getCanonicalType().getTypePtr()->isBuiltinType(); } }
bool TraverseType(clang::QualType type) { if (type.isNull()) { return PARENT::TraverseType(type); } auto node = std::make_unique<GenericAstNode>(); //node->myType = d; node->name = type->getTypeClassName(); auto nodePtr = node.get(); myStack.back()->attach(std::move(node)); myStack.push_back(nodePtr); auto res = PARENT::TraverseType(type); myStack.pop_back(); return res; }
Value::Value(clang::QualType clangTy, Interpreter& Interp): m_StorageType(determineStorageType(clangTy)), m_Type(clangTy.getAsOpaquePtr()), m_Interpreter(&Interp) { if (needsManagedAllocation()) ManagedAllocate(); }
int TypeUtils::sizeOfPointer(const clang::CompilerInstance &ci, clang::QualType qt) { if (!qt.getTypePtrOrNull()) return -1; // HACK: What's a better way of getting the size of a pointer ? auto &astContext = ci.getASTContext(); return astContext.getTypeSize(astContext.getPointerType(qt)); }
CompilerType::CompilerType(clang::ASTContext *ast, clang::QualType qual_type) : m_type(qual_type.getAsOpaquePtr()), m_type_system(ClangASTContext::GetASTContext(ast)) { #ifdef LLDB_CONFIGURATION_DEBUG if (m_type) assert(m_type_system != nullptr); #endif }
bool MocNg::ShouldRegisterMetaType(clang::QualType T) { if (T->isVoidType() || (T->isReferenceType() && !T.getNonReferenceType().isConstQualified())) return false; if (registered_meta_type.count(T->getCanonicalTypeUnqualified().getTypePtr())) return true; T = T.getNonReferenceType(); if (T->isPointerType()) { // registering pointer to forward declared type fails. const clang::CXXRecordDecl* Pointee = T->getPointeeCXXRecordDecl(); if (Pointee && !Pointee->hasDefinition()) return false; return true; } const clang::ClassTemplateSpecializationDecl* TD = llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(T->getAsCXXRecordDecl()); if (TD) { if (!TD->hasDefinition()) return false; for (uint I = 0; I < TD->getTemplateArgs().size(); ++I) { const auto &Arg = TD->getTemplateArgs().get(I); if (Arg.getKind() == clang::TemplateArgument::Type) { if (!ShouldRegisterMetaType(Arg.getAsType())) return false; } } } return true; }
static void StreamObj(llvm::raw_ostream& o, const void* V, clang::QualType Ty) { if (clang::CXXRecordDecl* CXXRD = Ty->getAsCXXRecordDecl()) { std::string QualName = CXXRD->getQualifiedNameAsString(); if (QualName == "cling::Value"){ StreamClingValue(o, (const cling::Value*)V); return; } } // if CXXRecordDecl // TODO: Print the object members. o << "@" << V; }
void ValuePrinterInfo::Init(clang::QualType Ty) { assert(!Ty.isNull() && "Type must be valid!"); assert(m_Context && "ASTContext cannot be null!"); assert(sizeof(m_Type) >= sizeof(clang::QualType) && "m_Type too small!"); m_Type = *reinterpret_cast<void**>(&Ty); // 1. Get the flags if (Ty.isLocalConstQualified() || Ty.isConstant(*m_Context)){ m_Flags |= VPI_Const; } if (Ty->isPointerType()) { // treat arrary-to-pointer decay as array: QualType PQT = Ty->getPointeeType(); const Type* PTT = PQT.getTypePtr(); if (!PTT || !PTT->isArrayType()) { m_Flags |= VPI_Ptr; if (const RecordType* RT = dyn_cast<RecordType>(Ty.getTypePtr())) if (RecordDecl* RD = RT->getDecl()) { CXXRecordDecl* CRD = dyn_cast<CXXRecordDecl>(RD); if (CRD && CRD->isPolymorphic()) m_Flags |= VPI_Polymorphic; } } } }
std::string GetTypeAsString(const clang::QualType &type) { std::stringstream stream; std::string name = type.getAsString(); // If it is an anonymous structure, print all the fields recursively if (name.substr(0,11) == "struct (ano") { stream << "struct { "; clang::RecordDecl* struct_decl = type.getTypePtr()->getAsStructureType()->getDecl(); // Print the types of all the fields for (const auto* field : struct_decl->fields()) { std::string type = GetTypeAsString(field->getType().getCanonicalType()); std::string name = field->getName(); stream << type; stream << " " << name << "; "; } stream << "}"; } else if (type.getTypePtr()->isBooleanType()) { return "bool"; } else { stream << type.getAsString(); //just print the type } return stream.str(); }
static StringRef getTypeName(clang::QualType qt) { if (auto typedefTy = qt->getAs<clang::TypedefType>()) { // Check for a CF type name (drop the "Ref") auto cfName = getCFTypeName(typedefTy->getDecl()->getCanonicalDecl()); if (cfName != StringRef()) return cfName; } auto identInfo = qt.getBaseTypeIdentifier(); if (identInfo) return identInfo->getName(); // Otherwise, no name return {}; }
// GET VECTOR TYPE FROM STRING rapidjson::Value SuperastCPP::createVectorValue(const clang::QualType qualType) { assert(isSTLVectorType(qualType)); //rapidjson::Value vectorValue(rapidjson::kObjectType); //vectorValue.AddMember("id", currentId++, allocator); const std::string& typeName = qualType.getAsString(); std::size_t actPos = 0; bool finished = false; unsigned depth = 0; std::string innerMostType; while (!finished) { // find next vector or comma std::size_t vectorPos = typeName.find(VECTOR_TYPE, actPos); std::size_t commaPos = typeName.find(",", actPos); std::string type = "vector"; if (commaPos < vectorPos) { finished = true; innerMostType = typeName.substr(actPos, commaPos-actPos); auto it = VECTOR_TYPE_MAPPING.find(type); if (it != VECTOR_TYPE_MAPPING.end()) innerMostType = it->second; } else { actPos = vectorPos + VECTOR_TYPE.size(); ++depth; } } rapidjson::Value actTypeValue(rapidjson::kObjectType); addId(actTypeValue); actTypeValue.AddMember("name", rapidjson::Value().SetString(innerMostType.c_str(), innerMostType.size(), allocator), allocator); for (unsigned i = 0; i < depth; ++i) { rapidjson::Value aux(rapidjson::kObjectType); addId(aux); aux.AddMember("name", "vector", allocator); aux.AddMember("data-type", actTypeValue, allocator); actTypeValue = aux; } return actTypeValue; }
// updates S.Ok; and, depending on Kind, possibly S.FnAccumulatorOk or S.FnOutConverterOk void RSExportReduce::checkPointeeConstQualified(StateOfAnalyzeTranslationUnit &S, FnIdent Kind, const llvm::StringRef &Name, const clang::ParmVarDecl *Param, bool ExpectedQualification) { const clang::QualType ParamQType = Param->getType(); slangAssert(ParamQType->isPointerType()); const clang::QualType PointeeQType = ParamQType->getPointeeType(); if (PointeeQType.isConstQualified() != ExpectedQualification) { S.RSC.ReportError(Param->getLocation(), "%0 parameter '%1' (type '%2') must%3 point to const-qualified type") << S.DiagnosticDescription(getKey(Kind), Name) << Param->getName() << ParamQType.getAsString() << (ExpectedQualification ? "" : " not"); notOk(S, Kind); } }
Value::EStorageType Value::determineStorageType(clang::QualType QT) { const clang::Type* desugCanon = QT.getCanonicalType().getTypePtr(); if (desugCanon->isSignedIntegerOrEnumerationType()) return kSignedIntegerOrEnumerationType; else if (desugCanon->isUnsignedIntegerOrEnumerationType()) return kUnsignedIntegerOrEnumerationType; else if (desugCanon->isRealFloatingType()) { const clang::BuiltinType* BT = desugCanon->getAs<clang::BuiltinType>(); if (BT->getKind() == clang::BuiltinType::Double) return kDoubleType; else if (BT->getKind() == clang::BuiltinType::Float) return kFloatType; else if (BT->getKind() == clang::BuiltinType::LongDouble) return kLongDoubleType; } else if (desugCanon->isPointerType() || desugCanon->isObjectType() || desugCanon->isReferenceType()) { if (desugCanon->isRecordType() || desugCanon->isConstantArrayType() || desugCanon->isMemberPointerType()) return kManagedAllocation; return kPointerType; } return kUnsupportedType; }
void RSExportReduce::analyzeResultType(StateOfAnalyzeTranslationUnit &S) { if (!(S.FnAccumulatorOk && S.FnOutConverterOk)) { // No idea what the result type is slangAssert(!S.Ok); return; } struct ResultInfoType { const clang::QualType QType; clang::VarDecl *const Decl; const char *FnKey; const std::string &FnName; std::function<std::string ()> UnlessOutConverter; } ResultInfo = S.FnOutConverter ? ResultInfoType({ S.FnOutConverterParamFirstTy, S.FnOutConverterParamFirst, KeyOutConverter, mNameOutConverter, []() { return std::string(""); }}) : ResultInfoType({ S.FnAccumulatorParamFirstTy, S.FnAccumulatorParamFirst, KeyAccumulator, mNameAccumulator, []() { return std::string(" unless ") + KeyOutConverter + " is provided"; }}); const clang::QualType PointeeQType = ResultInfo.QType->getPointeeType(); if (PointeeQType->isPointerType()) { S.RSC.ReportError(ResultInfo.Decl->getLocation(), "%0 parameter '%1' (type '%2') must not point to a pointer%3") << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName) << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString() << ResultInfo.UnlessOutConverter(); } else if (PointeeQType->isIncompleteType()) { S.RSC.ReportError(ResultInfo.Decl->getLocation(), "%0 parameter '%1' (type '%2') must not point to an incomplete type%3") << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName) << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString() << ResultInfo.UnlessOutConverter(); } else if (HasRSObjectType(PointeeQType.getTypePtr())) { S.RSC.ReportError(ResultInfo.Decl->getLocation(), "%0 parameter '%1' (type '%2') must not point to data containing an object type%3") << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName) << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString() << ResultInfo.UnlessOutConverter(); } else if (RSExportType::ValidateType(&S.RSC, S.ASTC, PointeeQType, ResultInfo.Decl, ResultInfo.Decl->getLocStart(), S.RSC.getTargetAPI(), false /* IsFilterscript */, true /* IsExtern */)) { // TODO: Better diagnostics on validation or creation failure? if ((mResultType = RSExportType::Create(&S.RSC, PointeeQType.getTypePtr(), NotLegacyKernelArgument, ResultInfo.Decl)) != nullptr) { const RSExportType *CheckType = mResultType; const char *ArrayErrorPhrase = ""; if (mResultType->getClass() == RSExportType::ExportClassConstantArray) { CheckType = static_cast<const RSExportConstantArrayType *>(mResultType)->getElementType(); ArrayErrorPhrase = "n array of"; } switch (CheckType->getClass()) { case RSExportType::ExportClassMatrix: // Not supported for now -- what does a matrix result type mean? S.RSC.ReportError(ResultInfo.Decl->getLocation(), "%0 parameter '%1' (type '%2') must not point to a%3 matrix type%4") << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName) << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString() << ArrayErrorPhrase << ResultInfo.UnlessOutConverter(); mResultType = nullptr; break; default: // All's well break; } } } if (mResultType) S.RSC.insertExportReduceResultType(mResultType); else S.Ok = false; }
insieme::core::TypePtr VariableLengthArrayExtension::Visit(const clang::QualType& type, insieme::frontend::conversion::Converter& converter) { // we iterate trough the dimensions of the array from left to right. There is no hint // in the C standard how this should be handled and therefore the normal operator precedence is used. if(const clang::VariableArrayType* arrType = llvm::dyn_cast<clang::VariableArrayType>(type.getTypePtr())) { // check if we already converted this decl if(::containsKey(arrayTypeMap, arrType)) return arrayTypeMap[arrType]; // only consider variable array types // create a decl stmt e.g., decl uint v1 = i; core::IRBuilder builder = converter.getIRBuilder(); auto index = converter.convertExpr(arrType->getSizeExpr()); // cast needed from rhs type to int<inf>?! if(index->getType() != builder.getLangBasic().getUIntInf()) { index = builder.numericCast(index, builder.getLangBasic().getUIntInf()); } auto decl = builder.declarationStmt(builder.getLangBasic().getUIntInf(), index); sizes.push_back(decl); // convert the element type (in nested array case this is again a variable array type) core::TypePtr elementType = converter.convertType(arrType->getElementType()); core::TypePtr arrayType = builder.arrayType(elementType, decl->getVariable()); // add type to map arrayTypeMap[arrType] = arrayType; return arrayType; } return nullptr; }
ASTDumper::ASTDumper (clang::QualType type) { m_dump = type.getAsString(); }
static void StreamValue(llvm::raw_ostream& o, const void* V, clang::QualType Ty, cling::Interpreter& Interp) { clang::ASTContext& C = Interp.getCI()->getASTContext(); if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(Ty.getCanonicalType())) { switch (BT->getKind()) { case clang::BuiltinType::Bool: if (*(const bool*)V) o << "true"; else o << "false"; break; case clang::BuiltinType::Char_U: // intentional fall through case clang::BuiltinType::UChar: // intentional fall through case clang::BuiltinType::Char_S: // intentional fall through case clang::BuiltinType::SChar: StreamChar(o, *(const char*)V); break; case clang::BuiltinType::Short: o << *(const short*)V; break; case clang::BuiltinType::UShort: o << *(const unsigned short*)V; break; case clang::BuiltinType::Int: o << *(const int*)V; break; case clang::BuiltinType::UInt: o << *(const unsigned int*)V; break; case clang::BuiltinType::Long: o << *(const long*)V; break; case clang::BuiltinType::ULong: o << *(const unsigned long*)V; break; case clang::BuiltinType::LongLong: o << *(const long long*)V; break; case clang::BuiltinType::ULongLong: o << *(const unsigned long long*)V; break; case clang::BuiltinType::Float: o << *(const float*)V; break; case clang::BuiltinType::Double: o << *(const double*)V; break; case clang::BuiltinType::LongDouble: { std::stringstream ssLD; ssLD << *(const long double*)V; o << ssLD.str() << 'L'; break; } default: StreamObj(o, V, Ty); } } else if (Ty.getAsString().compare("std::string") == 0) { StreamObj(o, V, Ty); o << " "; // force a space o <<"c_str: "; StreamCharPtr(o, ((const char*) (*(const std::string*)V).c_str())); } else if (Ty->isEnumeralType()) { clang::EnumDecl* ED = Ty->getAs<clang::EnumType>()->getDecl(); uint64_t value = *(const uint64_t*)V; bool IsFirst = true; llvm::APSInt ValAsAPSInt = C.MakeIntValue(value, Ty); for (clang::EnumDecl::enumerator_iterator I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E; ++I) { if (I->getInitVal() == ValAsAPSInt) { if (!IsFirst) { o << " ? "; } o << "(" << I->getQualifiedNameAsString() << ")"; IsFirst = false; } } o << " : (int) " << ValAsAPSInt.toString(/*Radix = */10); } else if (Ty->isReferenceType()) StreamRef(o, (const void**)&V, Ty, Interp); else if (Ty->isPointerType()) { clang::QualType PointeeTy = Ty->getPointeeType(); if (PointeeTy->isCharType()) StreamCharPtr(o, (const char*)V); else if (PointeeTy->isFunctionProtoType()) StreamFunction(o, V, PointeeTy, Interp); else StreamPtr(o, V); } else if (Ty->isArrayType()) StreamArr(o, V, Ty, Interp); else if (Ty->isFunctionType()) StreamFunction(o, V, Ty, Interp); else StreamObj(o, V, Ty); }
const std::string WebCLConfiguration::getNameOfType(clang::QualType type) const { return type.getUnqualifiedType().getAsString(); }
// Process "void combinename(compType *accum, const compType *val)" void RSExportReduce::analyzeCombiner(StateOfAnalyzeTranslationUnit &S) { if (S.FnCombiner) { // Must return void checkVoidReturn(S, FN_IDENT_COMBINER, S.FnCombiner); // Must have exactly two parameters, of same type as first accumulator parameter if (S.FnCombiner->getNumParams() != 2) { S.RSC.ReportError(S.FnCombiner->getLocation(), "%0 must take exactly 2 parameters (found %1)") << S.DiagnosticDescription(KeyCombiner, mNameCombiner) << S.FnCombiner->getNumParams(); S.Ok = false; return; } if (S.FnAccumulatorParamFirstTy.isNull() || !S.FnAccumulatorParamFirstTy->isPointerType()) { // We're already in an error situation. We could compare // against the initializer parameter type instead of the first // accumulator parameter type (we'd have to check for the // availability of a parameter type there, too), but it does not // seem worth the effort. // // Likewise, we could compare the two combiner parameter types // against each other. slangAssert(!S.Ok); return; } for (int ParamIdx = 0; ParamIdx < 2; ++ParamIdx) { const clang::ParmVarDecl *const FnCombinerParam = S.FnCombiner->getParamDecl(ParamIdx); const clang::QualType FnCombinerParamTy = FnCombinerParam->getType().getCanonicalType(); if (!FnCombinerParamTy->isPointerType() || !S.FnCombiner->getASTContext().hasSameUnqualifiedType( S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(), FnCombinerParamTy->getPointeeType().getCanonicalType())) { // <combiner> parameter '<baz>' (type '<tbaz>') // and accumulator <goo>() parameter '<gaz>' (type '<tgaz>') must be pointers to the same type S.RSC.ReportError(S.FnCombiner->getLocation(), "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')" " must be pointers to the same type") << S.DiagnosticDescription(KeyCombiner, mNameCombiner) << FnCombinerParam->getName() << FnCombinerParamTy.getAsString() << KeyAccumulator << mNameAccumulator << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString(); S.Ok = false; } else { // Check const-qualification checkPointeeConstQualified(S, FN_IDENT_COMBINER, mNameCombiner, FnCombinerParam, ParamIdx==1); } } return; } // Ensure accumulator properties permit omission of combiner. if (!S.FnAccumulatorOk) { // Couldn't fully analyze accumulator, so cannot see whether it permits omission of combiner. return; } if (mAccumulatorIns.size() != 1 || S.FnAccumulatorIndexOfFirstSpecialParameter != S.FnAccumulator->getNumParams()) { S.RSC.ReportError(S.FnAccumulator->getLocation(), "%0 must have exactly 1 input" " and no special parameters in order for the %1 to be omitted") << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator) << KeyCombiner; S.Ok = false; return; } const clang::ParmVarDecl *const FnAccumulatorParamInput = S.FnAccumulator->getParamDecl(1); const clang::QualType FnAccumulatorParamInputTy = FnAccumulatorParamInput->getType().getCanonicalType(); if (!S.FnAccumulator->getASTContext().hasSameUnqualifiedType( S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(), FnAccumulatorParamInputTy.getCanonicalType())) { S.RSC.ReportError(S.FnAccumulator->getLocation(), "%0 parameter '%1' (type '%2')" " must be pointer to the type of parameter '%3' (type '%4')" " in order for the %5 to be omitted") << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator) << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString() << FnAccumulatorParamInput->getName() << FnAccumulatorParamInputTy.getAsString() << KeyCombiner; S.Ok = false; } }
const std::string WebCLConfiguration::getNameOfAddressSpace(clang::QualType type) const { return getNameOfAddressSpace(type.getAddressSpace()); }
// Process "void outconvertname(resultType *result, const compType *accum)" void RSExportReduce::analyzeOutConverter(StateOfAnalyzeTranslationUnit &S) { if (!S.FnOutConverter) // outconverter is always optional return; // Must return void checkVoidReturn(S, FN_IDENT_OUT_CONVERTER, S.FnOutConverter); // Must have exactly two parameters if (S.FnOutConverter->getNumParams() != 2) { S.RSC.ReportError(S.FnOutConverter->getLocation(), "%0 must take exactly 2 parameters (found %1)") << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter) << S.FnOutConverter->getNumParams(); S.Ok = S.FnOutConverterOk = false; return; } // Parameters must not be special and must be of pointer type; // and second parameter must match first accumulator parameter for (int ParamIdx = 0; ParamIdx < 2; ++ParamIdx) { clang::ParmVarDecl *const FnOutConverterParam = S.FnOutConverter->getParamDecl(ParamIdx); if (isSpecialKernelParameter(FnOutConverterParam->getName())) { S.RSC.ReportError(S.FnOutConverter->getLocation(), "%0 cannot take special parameter '%1'") << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter) << FnOutConverterParam->getName(); S.Ok = S.FnOutConverterOk = false; continue; } const clang::QualType FnOutConverterParamTy = FnOutConverterParam->getType().getCanonicalType(); if (!FnOutConverterParamTy->isPointerType()) { S.RSC.ReportError(S.FnOutConverter->getLocation(), "%0 parameter '%1' must be of pointer type not '%2'") << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter) << FnOutConverterParam->getName() << FnOutConverterParamTy.getAsString(); S.Ok = S.FnOutConverterOk = false; continue; } // Check const-qualification checkPointeeConstQualified(S, FN_IDENT_OUT_CONVERTER, mNameOutConverter, FnOutConverterParam, ParamIdx==1); if (ParamIdx == 0) { S.FnOutConverterParamFirst = FnOutConverterParam; S.FnOutConverterParamFirstTy = FnOutConverterParamTy; continue; } if (S.FnAccumulatorParamFirstTy.isNull() || !S.FnAccumulatorParamFirstTy->isPointerType()) { // We're already in an error situation. We could compare // against the initializer parameter type instead of the first // accumulator parameter type (we'd have to check for the // availability of a parameter type there, too), but it does not // seem worth the effort. slangAssert(!S.Ok); continue; } if (!S.FnOutConverter->getASTContext().hasSameUnqualifiedType( S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(), FnOutConverterParamTy->getPointeeType().getCanonicalType())) { // <outconverter> parameter '<baz>' (type '<tbaz>') // and accumulator <goo>() parameter '<gaz>' (type '<tgaz>') must be pointers to the same type S.RSC.ReportError(S.FnOutConverter->getLocation(), "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')" " must be pointers to the same type") << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter) << FnOutConverterParam->getName() << FnOutConverterParamTy.getAsString() << KeyAccumulator << mNameAccumulator << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString(); S.Ok = S.FnOutConverterOk = false; } } }
std::string UWrapperGeneratorVB6Declare::ClangTypeToVB6(const clang::QualType& type, bool* success, bool canHaveRef, bool* isRef /*= 0*/) { if (isRef) *isRef = false; if (type->isFunctionPointerType()) { return "Long"; } else if (type->getTypeClass() == clang::Type::Builtin) { const clang::BuiltinType* builtInType = type->getAs<clang::BuiltinType>(); return ClangBuiltinTypeToVB6(builtInType, success); } else if (type->getTypeClass() == clang::Type::Pointer) { const clang::PointerType* pointerType = type->getAs<clang::PointerType>(); const clang::QualType& pointeeType = pointerType->getPointeeType(); if (pointeeType->getTypeClass() == clang::Type::Builtin) { const clang::BuiltinType* pointeeTypeBuiltin = pointeeType->getAs<clang::BuiltinType>(); switch (pointeeTypeBuiltin->getKind()) { case clang::BuiltinType::SChar: case clang::BuiltinType::Char_S: case clang::BuiltinType::UChar: case clang::BuiltinType::Char_U: return "String"; //char* --> String case clang::BuiltinType::Void: return "Long"; // void* --> Long default: if (m_ptrToLong) return "Long"; if (canHaveRef) { if (isRef) *isRef = true; return ClangBuiltinTypeToVB6(pointeeTypeBuiltin, success); } } } if (m_ptrToLong) return "Long"; std::string conv = ClangTypeToVB6(pointeeType, success, false); if (canHaveRef) { if (isRef) *isRef = true; return conv; } return "Long"; } else if (type->getTypeClass() == clang::Type::Typedef) { return ClangTypeToVB6(type->getAs<clang::TypedefType>()->desugar(), success, canHaveRef, isRef); } else if (type->getTypeClass() == clang::Type::Elaborated) { return ClangTypeToVB6(type->getAs<clang::ElaboratedType>()->desugar(), success, canHaveRef, isRef); } else if (type->getTypeClass() == clang::Type::Paren) { return ClangTypeToVB6(type->getAs<clang::ParenType>()->desugar(), success, canHaveRef, isRef); } else if (type->getTypeClass() == clang::Type::Enum) { const clang::EnumType* enumType = type->getAs<clang::EnumType>(); if (m_collectedEnums.find(enumType->getDecl()) != m_collectedEnums.end()) { return clang::QualType(enumType, 0).getAsString(); } } else if (type->getTypeClass() == clang::Type::Record) { const clang::RecordType* recType = type->getAs<clang::RecordType>(); if (m_collectedRecords.find(recType->getDecl()) != m_collectedRecords.end()) return recType->getDecl()->getNameAsString(); } if (success) *success = false; std::cout << type->getTypeClassName() << std::endl; type->dump(); return "<Unsupported>"; }
// Process "bool haltername(const compType *accum)" void RSExportReduce::analyzeHalter(StateOfAnalyzeTranslationUnit &S) { if (!S.FnHalter) // halter is always optional return; // Must return bool const clang::QualType ReturnTy = S.FnHalter->getReturnType().getCanonicalType(); if (!ReturnTy->isBooleanType()) { S.RSC.ReportError(S.FnHalter->getLocation(), "%0 must return bool not '%1'") << S.DiagnosticDescription(KeyHalter, mNameHalter) << ReturnTy.getAsString(); S.Ok = false; } // Must have exactly one parameter if (S.FnHalter->getNumParams() != 1) { S.RSC.ReportError(S.FnHalter->getLocation(), "%0 must take exactly 1 parameter (found %1)") << S.DiagnosticDescription(KeyHalter, mNameHalter) << S.FnHalter->getNumParams(); S.Ok = false; return; } // Parameter must not be a special parameter const clang::ParmVarDecl *const FnHalterParam = S.FnHalter->getParamDecl(0); if (isSpecialKernelParameter(FnHalterParam->getName())) { S.RSC.ReportError(S.FnHalter->getLocation(), "%0 cannot take special parameter '%1'") << S.DiagnosticDescription(KeyHalter, mNameHalter) << FnHalterParam->getName(); S.Ok = false; return; } // Parameter must be same type as first accumulator parameter if (S.FnAccumulatorParamFirstTy.isNull() || !S.FnAccumulatorParamFirstTy->isPointerType()) { // We're already in an error situation. We could compare against // the initializer parameter type or the first combiner parameter // type instead of the first accumulator parameter type (we'd have // to check for the availability of a parameter type there, too), // but it does not seem worth the effort. slangAssert(!S.Ok); return; } const clang::QualType FnHalterParamTy = FnHalterParam->getType().getCanonicalType(); if (!FnHalterParamTy->isPointerType() || !S.FnHalter->getASTContext().hasSameUnqualifiedType( S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(), FnHalterParamTy->getPointeeType().getCanonicalType())) { // <halter> parameter '<baz>' (type '<tbaz>') // and accumulator <goo>() parameter '<gaz>' (type '<tgaz>') must be pointers to the same type S.RSC.ReportError(S.FnHalter->getLocation(), "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')" " must be pointers to the same type") << S.DiagnosticDescription(KeyHalter, mNameHalter) << FnHalterParam->getName() << FnHalterParamTy.getAsString() << KeyAccumulator << mNameAccumulator << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString(); S.Ok = false; return; } // Parameter must point to const-qualified checkPointeeConstQualified(S, FN_IDENT_HALTER, mNameHalter, FnHalterParam, true); }
void CompilerType::SetCompilerType (clang::ASTContext *ast, clang::QualType qual_type) { m_type_system = ClangASTContext::GetASTContext(ast); m_type = qual_type.getAsOpaquePtr(); }