23#include "llvm/ADT/SmallSet.h"
24#include "llvm/IR/Constants.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Metadata.h"
27#include "llvm/IR/Module.h"
28#include "llvm/IR/Type.h"
30using namespace CodeGen;
35 : Context(Ctx),
Module(M), CodeGenOpts(CGO),
36 Features(Features), MContext(MContext), MDHelper(M.getContext()),
37 Root(nullptr), Char(nullptr)
43llvm::MDNode *CodeGenTBAA::getRoot() {
49 if (Features.CPlusPlus)
50 Root = MDHelper.createTBAARoot(
"Simple C++ TBAA");
52 Root = MDHelper.createTBAARoot(
"Simple C/C++ TBAA");
58llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
61 if (CodeGenOpts.NewStructPathTBAA) {
62 llvm::Metadata *
Id = MDHelper.createString(Name);
63 return MDHelper.createTBAATypeNode(
Parent, Size,
Id);
65 return MDHelper.createTBAAScalarTypeNode(Name,
Parent);
68llvm::MDNode *CodeGenTBAA::getChar() {
74 Char = createScalarTypeNode(
"omnipotent char", getRoot(), 1);
82 if (TD->hasAttr<MayAliasAttr>())
89 if (TT->getDecl()->hasAttr<MayAliasAttr>())
115llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(
const Type *Ty) {
119 if (
const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
120 switch (BTy->getKind()) {
126 case BuiltinType::Char_U:
127 case BuiltinType::Char_S:
128 case BuiltinType::UChar:
129 case BuiltinType::SChar:
133 case BuiltinType::UShort:
135 case BuiltinType::UInt:
137 case BuiltinType::ULong:
139 case BuiltinType::ULongLong:
141 case BuiltinType::UInt128:
144 case BuiltinType::UShortFract:
146 case BuiltinType::UFract:
148 case BuiltinType::ULongFract:
151 case BuiltinType::SatUShortFract:
153 case BuiltinType::SatUFract:
155 case BuiltinType::SatULongFract:
158 case BuiltinType::UShortAccum:
160 case BuiltinType::UAccum:
162 case BuiltinType::ULongAccum:
165 case BuiltinType::SatUShortAccum:
167 case BuiltinType::SatUAccum:
169 case BuiltinType::SatULongAccum:
176 return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
190 return createScalarTypeNode(
"any pointer", getChar(), Size);
193 if (CodeGenOpts.NewStructPathTBAA && Ty->
isArrayType())
194 return getTypeInfo(cast<ArrayType>(Ty)->getElementType());
198 if (
const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
203 if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())
207 llvm::raw_svector_ostream Out(OutName);
209 return createScalarTypeNode(OutName, getChar(), Size);
212 if (
const auto *EIT = dyn_cast<BitIntType>(Ty)) {
214 llvm::raw_svector_ostream Out(OutName);
217 Out <<
"_BitInt(" << EIT->getNumBits() <<
')';
218 return createScalarTypeNode(OutName, getChar(), Size);
227 if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
245 if (llvm::MDNode *N = MetadataCache[Ty])
251 llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
252 return MetadataCache[Ty] = TypeNode;
269 llvm::DataLayout DL(&
Module);
270 unsigned Size = DL.getPointerTypeSize(VTablePtrType);
271 return TBAAAccessInfo(createScalarTypeNode(
"vtable pointer", getRoot(), Size),
276CodeGenTBAA::CollectFields(uint64_t BaseOffset,
290 if (
Decl->bases_begin() !=
Decl->bases_end())
297 e = RD->
field_end(); i != e; ++i, ++idx) {
298 if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
300 uint64_t Offset = BaseOffset +
303 if (!CollectFields(Offset, FieldQTy, Fields,
311 uint64_t Offset = BaseOffset;
315 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
323 if (llvm::MDNode *N = StructMetadataCache[Ty])
328 return MDHelper.createTBAAStructNode(Fields);
331 return StructMetadataCache[Ty] =
nullptr;
334llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(
const Type *Ty) {
335 if (
auto *TTy = dyn_cast<RecordType>(Ty)) {
338 using TBAAStructField = llvm::MDBuilder::TBAAStructField;
340 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
344 if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
345 return BaseTypeMetadataCache[Ty] =
nullptr;
357 return BaseTypeMetadataCache[Ty] =
nullptr;
362 llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
370 [](
const TBAAStructField &A,
const TBAAStructField &B) {
371 return A.Offset < B.Offset;
375 if (
Field->isZeroSize(Context) ||
Field->isUnnamedBitfield())
381 return BaseTypeMetadataCache[Ty] =
nullptr;
386 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
391 if (Features.CPlusPlus) {
393 llvm::raw_svector_ostream Out(OutName);
399 if (CodeGenOpts.NewStructPathTBAA) {
400 llvm::MDNode *
Parent = getChar();
402 llvm::Metadata *
Id = MDHelper.createString(OutName);
403 return MDHelper.createTBAATypeNode(
Parent, Size,
Id, Fields);
408 for (
const auto &Field : Fields)
409 OffsetsAndTypes.push_back(std::make_pair(
Field.Type,
Field.Offset));
410 return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
421 if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
427 llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
428 return BaseTypeMetadataCache[Ty] = TypeNode;
432 assert(!Info.
isIncomplete() &&
"Access to an object of an incomplete type!");
440 if (!CodeGenOpts.StructPathTBAA)
443 llvm::MDNode *&N = AccessTagMetadataCache[Info];
449 assert(!Info.
Offset &&
"Nonzero offset for an access with no base type!");
451 if (CodeGenOpts.NewStructPathTBAA) {
472 if (!InfoA || !InfoB)
487 if (DestInfo == SrcInfo)
490 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 ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CanQualType SatLongAccumTy
CanQualType SatShortFractTy
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType SatLongFractTy
CanQualType SatShortAccumTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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 getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding,...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
This class is used for builtin types like 'int'.
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]).
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
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, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext)
TBAAAccessInfo getAccessInfo(QualType AccessType)
getAccessInfo - Get TBAA information that describes an access to an object of the given type.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Decl - This represents one declaration (or definition), e.g.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Represents a member of a struct/union/class.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
virtual void mangleTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
Describes a module or submodule.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
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.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Exposes information about the current target.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
bool isReferenceType() const
bool isStdByteType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAs() const
Member-template getAs<specific type>'.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
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