10#include "TargetInfo.h"
79class TypeStringCache {
80 enum Status {NonRecursive, Recursive,
Incomplete, IncompleteUsed};
87 std::map<const IdentifierInfo *, struct Entry> Map;
88 unsigned IncompleteCount;
89 unsigned IncompleteUsedCount;
91 TypeStringCache() : IncompleteCount(0), IncompleteUsedCount(0) {}
105 FieldEncoding(
bool b, SmallStringEnc &e) : HasName(
b), Enc(e.c_str()) {}
106 StringRef str() {
return Enc; }
107 bool operator<(
const FieldEncoding &rhs)
const {
108 if (HasName != rhs.HasName)
return HasName;
109 return Enc < rhs.Enc;
121 mutable TypeStringCache TSC;
122 void emitTargetMD(
const Decl *
D, llvm::GlobalValue *GV,
129 const llvm::MapVector<GlobalDecl, StringRef>
130 &MangledDeclNames)
const override;
148 CharUnits TypeAlign = getContext().getTypeAlignInChars(Ty);
149 llvm::Type *ArgTy = CGT.ConvertType(Ty);
152 llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy->getContext());
161 llvm_unreachable(
"Unsupported ABI kind for va_arg");
163 Val =
Address(llvm::UndefValue::get(ArgPtrTy), ArgTy, TypeAlign);
171 ArgSize = ArgSize.
alignTo(SlotSize);
176 Val =
Address(Builder.CreateLoad(Val), ArgTy, TypeAlign);
183 Address APN = Builder.CreateConstInBoundsByteGEP(AP, ArgSize);
196 std::string StubEnc) {
200 assert( (
E.Str.empty() ||
E.State == Recursive) &&
201 "Incorrectly use of addIncomplete");
202 assert(!StubEnc.empty() &&
"Passing an empty string to addIncomplete()");
203 E.Swapped.swap(
E.Str);
216 auto I = Map.find(ID);
217 assert(I != Map.end() &&
"Entry not present");
218 Entry &
E = I->second;
220 E.State == IncompleteUsed) &&
221 "Entry must be an incomplete type");
222 bool IsRecursive =
false;
223 if (
E.State == IncompleteUsed) {
226 --IncompleteUsedCount;
228 if (
E.Swapped.empty())
232 E.Swapped.swap(
E.Str);
242void TypeStringCache::addIfComplete(
const IdentifierInfo *ID, StringRef Str,
244 if (!ID || IncompleteUsedCount)
247 if (IsRecursive && !
E.Str.empty()) {
248 assert(
E.State==Recursive &&
E.Str.size() == Str.size() &&
249 "This is not the same Recursive entry");
255 assert(
E.Str.empty() &&
"Entry already present");
257 E.State = IsRecursive? Recursive : NonRecursive;
266 auto I = Map.find(ID);
269 Entry &
E = I->second;
270 if (
E.State == Recursive && IncompleteCount)
275 E.State = IncompleteUsed;
276 ++IncompleteUsedCount;
295 TypeStringCache &TSC);
298void XCoreTargetCodeGenInfo::emitTargetMD(
299 const Decl *
D, llvm::GlobalValue *GV,
303 llvm::LLVMContext &Ctx = CGM.
getModule().getContext();
304 llvm::Metadata *MDVals[] = {llvm::ConstantAsMetadata::get(GV),
305 llvm::MDString::get(Ctx, Enc.str())};
306 llvm::NamedMDNode *MD =
307 CGM.
getModule().getOrInsertNamedMetadata(
"xcore.typestrings");
308 MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
312void XCoreTargetCodeGenInfo::emitTargetMetadata(
314 const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames)
const {
318 for (
unsigned I = 0; I != MangledDeclNames.size(); ++I) {
319 auto Val = *(MangledDeclNames.begin() + I);
322 const Decl *
D = Val.first.getDecl()->getMostRecentDecl();
323 emitTargetMD(
D, GV, CGM);
330 TypeStringCache &TSC);
338 TypeStringCache &TSC) {
339 for (
const auto *Field : RD->
fields()) {
342 Enc += Field->getName();
344 if (Field->isBitField()) {
346 llvm::raw_svector_ostream OS(Enc);
347 OS << Field->getBitWidthValue();
350 if (!
appendType(Enc, Field->getType(), CGM, TSC))
352 if (Field->isBitField())
355 FE.emplace_back(!Field->getName().empty(), Enc);
367 StringRef TypeString = TSC.lookupStr(ID);
368 if (!TypeString.empty()) {
374 size_t Start = Enc.size();
378 Enc += ID->getName();
382 bool IsRecursive =
false;
389 std::string StubEnc(Enc.substr(Start).str());
391 TSC.addIncomplete(ID, std::move(StubEnc));
393 (void) TSC.removeIncomplete(ID);
396 IsRecursive = TSC.removeIncomplete(ID);
402 unsigned E = FE.size();
403 for (
unsigned I = 0; I !=
E; ++I) {
410 TSC.addIfComplete(ID, Enc.substr(Start), IsRecursive);
416 TypeStringCache &TSC,
419 StringRef TypeString = TSC.lookupStr(ID);
420 if (!TypeString.empty()) {
425 size_t Start = Enc.size();
428 Enc += ID->getName();
434 for (
auto I = ED->enumerator_begin(),
E = ED->enumerator_end(); I !=
E;
436 SmallStringEnc EnumEnc;
438 EnumEnc += I->getName();
440 I->getInitVal().toString(EnumEnc);
442 FE.push_back(FieldEncoding(!I->getName().empty(), EnumEnc));
445 unsigned E = FE.size();
446 for (
unsigned I = 0; I !=
E; ++I) {
453 TSC.addIfComplete(ID, Enc.substr(Start),
false);
461 static const char *
const Table[]={
"",
"c:",
"r:",
"cr:",
"v:",
"cv:",
"rv:",
"crv:"};
469 Enc += Table[Lookup];
476 case BuiltinType::Void:
479 case BuiltinType::Bool:
482 case BuiltinType::Char_U:
485 case BuiltinType::UChar:
488 case BuiltinType::SChar:
491 case BuiltinType::UShort:
494 case BuiltinType::Short:
497 case BuiltinType::UInt:
500 case BuiltinType::Int:
503 case BuiltinType::ULong:
506 case BuiltinType::Long:
509 case BuiltinType::ULongLong:
512 case BuiltinType::LongLong:
515 case BuiltinType::Float:
518 case BuiltinType::Double:
521 case BuiltinType::LongDouble:
534 TypeStringCache &TSC) {
546 TypeStringCache &TSC, StringRef NoSizeEnc) {
551 CAT->getSize().toStringUnsigned(Enc);
567 TypeStringCache &TSC) {
574 auto I = FPT->param_type_begin();
575 auto E = FPT->param_type_end();
584 if (FPT->isVariadic())
587 if (FPT->isVariadic())
601 TypeStringCache &TSC) {
632 TypeStringCache &TSC) {
639 return appendType(Enc, FD->getType(), CGM, TSC);
642 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D)) {
645 QualType QT = VD->getType().getCanonicalType();
657std::unique_ptr<TargetCodeGenInfo>
659 return std::make_unique<XCoreTargetCodeGenInfo>(CGM.
getTypes());
static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC, const IdentifierInfo *ID)
Appends structure and union types to Enc and adds encoding to cache.
static bool appendBuiltinType(SmallStringEnc &Enc, const BuiltinType *BT)
Appends built-in types to Enc.
static bool extractFieldType(SmallVectorImpl< FieldEncoding > &FE, const RecordDecl *RD, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
Helper function for appendRecordType().
static bool appendPointerType(SmallStringEnc &Enc, const PointerType *PT, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
Appends a pointer encoding to Enc before calling appendType for the pointee.
static bool appendFunctionType(SmallStringEnc &Enc, const FunctionType *FT, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
Appends a function encoding to Enc, calling appendType for the return type and the arguments.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static void appendQualifier(SmallStringEnc &Enc, QualType QT)
Appends type's qualifier to Enc.
static bool appendType(SmallStringEnc &Enc, QualType QType, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
Handles the type's qualifier before dispatching a call to handle specific type encodings.
static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET, TypeStringCache &TSC, const IdentifierInfo *ID)
Appends enum types to Enc and adds the encoding to the cache.
static bool appendArrayType(SmallStringEnc &Enc, QualType QT, const ArrayType *AT, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC, StringRef NoSizeEnc)
Appends array encoding to Enc before calling appendType for the element.
static CharUnits getTypeAllocSize(CodeGenModule &CGM, llvm::Type *type)
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
This class is used for builtin types like 'int'.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
void setCoerceToType(llvm::Type *T)
@ Extend
Extend - Valid only for integer argument types.
@ Ignore
Ignore - Ignore the argument (treat as void).
@ IndirectAliased
IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...
@ Expand
Expand - Only valid for aggregate argument types.
@ TargetSpecific
TargetSpecific - Some argument types are passed as target specific types such as RISC-V's tuple type,...
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
@ CoerceAndExpand
CoerceAndExpand - Only valid for aggregate argument types.
@ Direct
Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...
llvm::Type * getCoerceToType() const
bool canHaveCoerceToType() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
CodeGenTypes & getTypes()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
DefaultABIInfo - The default implementation for ABI specific details.
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, AggValueSlot Slot) const override
EmitVAArg - Emit the target dependent code to load a value of.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual void emitTargetMetadata(CodeGen::CodeGenModule &CGM, const llvm::MapVector< GlobalDecl, StringRef > &MangledDeclNames) const
emitTargetMetadata - Provides a convenient hook to handle extra target-specific metadata for the give...
Represents the canonical version of C arrays with a specified constant size.
Decl - This represents one declaration (or definition), e.g.
EnumDecl * getDefinition() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getOriginalDecl() const
Represents a function declaration or definition.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
const IdentifierInfo * getBaseTypeIdentifier() const
Retrieves a pointer to the name of the base type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs<specific type>'.
Represents a variable declaration or definition.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
llvm::Type * getVAListElementType(CodeGenFunction &CGF)
std::unique_ptr< TargetCodeGenInfo > createXCoreTargetCodeGenInfo(CodeGenModule &CGM)
The JSON file list parser is used to communicate input to InstallAPI.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Incomplete
Template argument deduction did not deduce a value for every template parameter.