28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Metadata.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/Type.h"
32#include "llvm/Support/Debug.h"
39 : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
47llvm::MDNode *CodeGenTBAA::getRoot() {
53 if (Features.CPlusPlus)
54 Root = MDHelper.createTBAARoot(
"Simple C++ TBAA");
56 Root = MDHelper.createTBAARoot(
"Simple C/C++ TBAA");
62llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
65 if (CodeGenOpts.NewStructPathTBAA) {
66 llvm::Metadata *Id = MDHelper.createString(Name);
67 return MDHelper.createTBAATypeNode(Parent, Size, Id);
69 return MDHelper.createTBAAScalarTypeNode(Name, Parent);
72llvm::MDNode *CodeGenTBAA::getChar() {
78 Char = createScalarTypeNode(
"omnipotent char", getRoot(), 1);
83llvm::MDNode *CodeGenTBAA::getAnyPtr(
unsigned PtrDepth) {
84 assert(PtrDepth >= 1 &&
"Pointer must have some depth");
103 if (AnyPtrs.size() < PtrDepth) {
104 AnyPtrs.reserve(PtrDepth);
105 auto Size = Module.getDataLayout().getPointerSize();
108 AnyPtrs.push_back(createScalarTypeNode(
"any pointer", getChar(), Size));
110 for (
size_t Idx = AnyPtrs.size(); Idx < PtrDepth; ++Idx) {
111 auto Name = (
"any p" + llvm::Twine(Idx + 1) +
" pointer").str();
112 AnyPtrs.push_back(createScalarTypeNode(Name, AnyPtrs[Idx - 1], Size));
116 return AnyPtrs[PtrDepth - 1];
122 if (TD->hasAttr<MayAliasAttr>())
129 if (TT->getDecl()->hasAttr<MayAliasAttr>())
147 if (!RD->isCompleteDefinition())
149 if (RD->hasFlexibleArrayMember())
153 if (RD->isStruct() || RD->isClass())
159llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(
const Type *Ty) {
160 uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
163 if (
const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
164 switch (BTy->getKind()) {
170 case BuiltinType::Char_U:
171 case BuiltinType::Char_S:
172 case BuiltinType::UChar:
173 case BuiltinType::SChar:
177 case BuiltinType::UShort:
179 case BuiltinType::UInt:
181 case BuiltinType::ULong:
183 case BuiltinType::ULongLong:
185 case BuiltinType::UInt128:
188 case BuiltinType::UShortFract:
190 case BuiltinType::UFract:
192 case BuiltinType::ULongFract:
195 case BuiltinType::SatUShortFract:
197 case BuiltinType::SatUFract:
199 case BuiltinType::SatULongFract:
202 case BuiltinType::UShortAccum:
204 case BuiltinType::UAccum:
206 case BuiltinType::ULongAccum:
209 case BuiltinType::SatUShortAccum:
211 case BuiltinType::SatUAccum:
213 case BuiltinType::SatULongAccum:
220 return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
247 if (!CodeGenOpts.PointerTBAA)
265 unsigned PtrDepth = 0;
276 return getAnyPtr(PtrDepth);
286 SmallString<256> TyName;
288 llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
291 ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
300 return getAnyPtr(PtrDepth);
313 if (!RT->getOriginalDecl()->getDeclName())
314 return getAnyPtr(PtrDepth);
317 llvm::raw_svector_ostream TyOut(TyName);
318 MangleCtx->mangleCanonicalTypeName(QualType(Ty, 0), TyOut);
321 SmallString<256> OutName(
"p");
322 OutName += std::to_string(PtrDepth);
325 return createScalarTypeNode(OutName, getAnyPtr(PtrDepth), Size);
329 if (CodeGenOpts.NewStructPathTBAA && Ty->
isArrayType())
334 if (
const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
335 const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
336 if (!Features.CPlusPlus)
346 SmallString<256> OutName;
347 llvm::raw_svector_ostream
Out(OutName);
348 CGTypes.getCXXABI().getMangleContext().mangleCanonicalTypeName(
349 QualType(ETy, 0), Out);
350 return createScalarTypeNode(OutName, getChar(), Size);
353 if (
const auto *EIT = dyn_cast<BitIntType>(Ty)) {
354 SmallString<256> OutName;
355 llvm::raw_svector_ostream
Out(OutName);
358 Out <<
"_BitInt(" << EIT->getNumBits() <<
')';
359 return createScalarTypeNode(OutName, getChar(), Size);
369 if (!Features.Sanitize.has(SanitizerKind::Type) &&
370 (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing))
386 return getValidBaseTypeInfo(QTy);
388 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
389 if (llvm::MDNode *N = MetadataCache[Ty])
395 llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
396 return MetadataCache[Ty] = TypeNode;
408 uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
413 const llvm::DataLayout &DL = Module.getDataLayout();
414 unsigned Size = DL.getPointerTypeSize(VTablePtrType);
415 return TBAAAccessInfo(createScalarTypeNode(
"vtable pointer", getRoot(), Size),
420CodeGenTBAA::CollectFields(uint64_t BaseOffset,
428 if (TTy->isUnionType()) {
429 uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
430 llvm::MDNode *TBAAType = getChar();
433 llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag));
442 if (!
Decl->bases().empty())
450 i != e; ++i, ++idx) {
459 if ((*i)->isBitField()) {
464 bool IsBE = Context.getTargetInfo().isBigEndian();
471 llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth());
472 llvm::MDNode *TBAAType = getChar();
473 llvm::MDNode *TBAATag =
476 llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
481 if (!CollectFields(Offset, FieldQTy, Fields,
490 uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
493 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
499 if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
502 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
504 if (llvm::MDNode *N = StructMetadataCache[Ty])
509 return MDHelper.createTBAAStructNode(Fields);
512 return StructMetadataCache[Ty] =
nullptr;
515llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(
const Type *Ty) {
516 if (
auto *TTy = dyn_cast<RecordType>(Ty)) {
519 using TBAAStructField = llvm::MDBuilder::TBAAStructField;
521 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
525 if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
535 ? getValidBaseTypeInfo(BaseQTy)
541 Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
543 llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
551 [](
const TBAAStructField &A,
const TBAAStructField &B) {
552 return A.Offset < B.Offset;
555 for (FieldDecl *Field : RD->
fields()) {
556 if (
Field->isZeroSize(Context) ||
Field->isUnnamedBitField())
558 QualType FieldQTy =
Field->getType();
560 ? getValidBaseTypeInfo(FieldQTy)
566 uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
567 uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity();
568 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
572 SmallString<256> OutName;
573 if (Features.CPlusPlus) {
575 llvm::raw_svector_ostream
Out(OutName);
576 CGTypes.getCXXABI().getMangleContext().mangleCanonicalTypeName(
577 QualType(Ty, 0), Out);
582 if (CodeGenOpts.NewStructPathTBAA) {
583 llvm::MDNode *Parent = getChar();
584 uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
585 llvm::Metadata *Id = MDHelper.createString(OutName);
586 return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields);
590 SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes;
591 for (
const auto &Field : Fields)
592 OffsetsAndTypes.push_back(std::make_pair(
Field.Type,
Field.Offset));
593 return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
599llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) {
602 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
605 auto I = BaseTypeMetadataCache.find(Ty);
606 if (I != BaseTypeMetadataCache.end())
611 llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
612 LLVM_ATTRIBUTE_UNUSED
auto inserted =
613 BaseTypeMetadataCache.insert({Ty, TypeNode});
614 assert(inserted.second &&
"BaseType metadata was already inserted");
624 assert(!Info.
isIncomplete() &&
"Access to an object of an incomplete type!");
632 if (!CodeGenOpts.StructPathTBAA)
635 llvm::MDNode *&N = AccessTagMetadataCache[Info];
641 assert(!Info.
Offset &&
"Nonzero offset for an access with no base type!");
643 if (CodeGenOpts.NewStructPathTBAA) {
664 if (!InfoA || !InfoB)
679 if (DestInfo == SrcInfo)
682 if (!DestInfo || !SrcInfo)
Defines the clang::ASTContext interface.
static bool TypeHasMayAlias(QualType QTy)
static bool isValidBaseType(QualType QTy)
Check if the given type is a valid base type to be used in access tags.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
llvm::MDNode * getBaseTypeInfo(QualType QTy)
getBaseTypeInfo - Get metadata that describes the given base access type.
llvm::MDNode * getTypeInfo(QualType QTy)
getTypeInfo - Get metadata used to describe accesses to objects of the given type.
TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType)
getVTablePtrAccessInfo - Get the TBAA information that describes an access to a virtual table pointer...
TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, TBAAAccessInfo SrcInfo)
mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the purpose of memory transfer calls...
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo)
mergeTBAAInfoForCast - Get merged TBAA information for the purpose of type casts.
TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, TBAAAccessInfo InfoB)
mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the purpose of conditional oper...
llvm::MDNode * getAccessTagInfo(TBAAAccessInfo Info)
getAccessTagInfo - Get TBAA tag for a given memory access.
llvm::MDNode * getTBAAStructInfo(QualType QTy)
getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of the given type.
CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features)
TBAAAccessInfo getAccessInfo(QualType AccessType)
getAccessInfo - Get TBAA information that describes an access to an object of the given type.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
Decl - This represents one declaration (or definition), e.g.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool isExternallyVisible() const
A (possibly-)qualified type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
Exposes information about the current target.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
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>'.
Defines the clang::TargetInfo interface.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)
Structure with information about how a bitfield should be accessed.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
llvm::MDNode * AccessType
AccessType - The final access type.
uint64_t Offset
Offset - The byte offset of the final access within the base one.
static TBAAAccessInfo getMayAliasInfo()
uint64_t Size
Size - The size of access, in bytes.
static TBAAAccessInfo getIncompleteInfo()
llvm::MDNode * BaseType
BaseType - The base/leading access type.
bool isIncomplete() const