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) {}
92 void addIncomplete(
const IdentifierInfo *ID, std::string StubEnc);
93 bool removeIncomplete(
const IdentifierInfo *ID);
94 void addIfComplete(
const IdentifierInfo *ID, StringRef Str,
96 StringRef lookupStr(
const IdentifierInfo *ID);
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;
115 XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
116 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
117 AggValueSlot Slot)
const override;
121 mutable TypeStringCache TSC;
122 void emitTargetMD(
const Decl *D, llvm::GlobalValue *GV,
123 const CodeGen::CodeGenModule &M)
const;
126 XCoreTargetCodeGenInfo(CodeGenTypes &CGT)
127 : TargetCodeGenInfo(std::make_unique<XCoreABIInfo>(CGT)) {}
128 void emitTargetMetadata(CodeGen::CodeGenModule &CGM,
129 const llvm::MapVector<GlobalDecl, StringRef>
130 &MangledDeclNames)
const override;
139 CGBuilderTy &Builder = CGF.
Builder;
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);
195void TypeStringCache::addIncomplete(
const IdentifierInfo *ID,
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);
213bool TypeStringCache::removeIncomplete(
const IdentifierInfo *ID) {
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;
263StringRef TypeStringCache::lookupStr(
const IdentifierInfo *ID) {
266 auto I = Map.find(ID);
269 Entry &E = I->second;
270 if (E.State == Recursive && IncompleteCount)
275 E.State = IncompleteUsed;
276 ++IncompleteUsedCount;
294 const CodeGen::CodeGenModule &CGM,
295 TypeStringCache &TSC);
298void XCoreTargetCodeGenInfo::emitTargetMD(
299 const Decl *D, llvm::GlobalValue *GV,
300 const CodeGen::CodeGenModule &CGM)
const {
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(
313 CodeGen::CodeGenModule &CGM,
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);
328static bool appendType(SmallStringEnc &Enc, QualType QType,
329 const CodeGen::CodeGenModule &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();
375 Enc += (RT->isUnionType()?
'u' :
's');
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);
399 if (RT->isUnionType())
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) {
636 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
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'.
bool isZero() const
Test whether the quantity equals zero.
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
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)
DefaultABIInfo - The default implementation for ABI specific details.
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,...
Represents the canonical version of C arrays with a specified constant size.
Decl - This represents one declaration (or definition), e.g.
EnumDecl * getDefinition() 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.
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.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Type * getVAListElementType(CodeGenFunction &CGF)
std::unique_ptr< TargetCodeGenInfo > createXCoreTargetCodeGenInfo(CodeGenModule &CGM)
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Incomplete
Template argument deduction did not deduce a value for every template parameter.