24 #include "llvm/ADT/SmallSet.h" 25 #include "llvm/IR/Constants.h" 26 #include "llvm/IR/LLVMContext.h" 27 #include "llvm/IR/Metadata.h" 28 #include "llvm/IR/Module.h" 29 #include "llvm/IR/Type.h" 30 using namespace clang;
31 using namespace CodeGen;
36 : Context(Ctx),
Module(M), CodeGenOpts(CGO),
37 Features(Features), MContext(MContext), MDHelper(M.getContext()),
38 Root(nullptr), Char(nullptr)
44 llvm::MDNode *CodeGenTBAA::getRoot() {
50 if (Features.CPlusPlus)
51 Root = MDHelper.createTBAARoot(
"Simple C++ TBAA");
53 Root = MDHelper.createTBAARoot(
"Simple C/C++ TBAA");
59 llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
62 if (CodeGenOpts.NewStructPathTBAA) {
63 llvm::Metadata *
Id = MDHelper.createString(Name);
64 return MDHelper.createTBAATypeNode(
Parent, Size, Id);
66 return MDHelper.createTBAAScalarTypeNode(Name,
Parent);
69 llvm::MDNode *CodeGenTBAA::getChar() {
75 Char = createScalarTypeNode(
"omnipotent char", getRoot(), 1);
82 if (
const TagType *TTy = dyn_cast<TagType>(QTy))
83 return TTy->getDecl()->hasAttr<MayAliasAttr>();
86 if (
const TypedefType *TTy = dyn_cast<TypedefType>(QTy)) {
87 if (TTy->getDecl()->hasAttr<MayAliasAttr>())
115 llvm::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:
148 return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
162 return createScalarTypeNode(
"any pointer", getChar(), Size);
165 if (CodeGenOpts.NewStructPathTBAA && Ty->
isArrayType())
166 return getTypeInfo(cast<ArrayType>(Ty)->getElementType());
170 if (
const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
175 if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())
179 llvm::raw_svector_ostream Out(OutName);
181 return createScalarTypeNode(OutName, getChar(), Size);
190 if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
208 if (llvm::MDNode *N = MetadataCache[Ty])
214 llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
215 return MetadataCache[Ty] = TypeNode;
219 llvm::DataLayout DL(&
Module);
220 unsigned Size = DL.getPointerTypeSize(VTablePtrType);
221 return TBAAAccessInfo(createScalarTypeNode(
"vtable pointer", getRoot(), Size),
226 CodeGenTBAA::CollectFields(uint64_t BaseOffset,
240 if (
Decl->bases_begin() !=
Decl->bases_end())
247 e = RD->
field_end(); i != e; ++i, ++idx) {
248 uint64_t
Offset = BaseOffset +
251 if (!CollectFields(Offset, FieldQTy, Fields,
259 uint64_t
Offset = BaseOffset;
261 llvm::MDNode *TBAAType = MayAlias ? getChar() :
getTypeInfo(QTy);
263 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
271 if (llvm::MDNode *N = StructMetadataCache[Ty])
276 return MDHelper.createTBAAStructNode(Fields);
279 return StructMetadataCache[Ty] =
nullptr;
282 llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(
const Type *Ty) {
283 if (
auto *TTy = dyn_cast<RecordType>(Ty)) {
288 QualType FieldQTy = Field->getType();
292 return BaseTypeMetadataCache[Ty] =
nullptr;
294 uint64_t BitOffset = Layout.
getFieldOffset(Field->getFieldIndex());
297 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
302 if (Features.CPlusPlus) {
304 llvm::raw_svector_ostream Out(OutName);
310 if (CodeGenOpts.NewStructPathTBAA) {
311 llvm::MDNode *
Parent = getChar();
313 llvm::Metadata *
Id = MDHelper.createString(OutName);
314 return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields);
319 for (
const auto &Field : Fields)
320 OffsetsAndTypes.push_back(std::make_pair(Field.Type, Field.Offset));
321 return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
332 if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
338 llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
339 return BaseTypeMetadataCache[Ty] = TypeNode;
343 assert(!Info.
isIncomplete() &&
"Access to an object of an incomplete type!");
351 if (!CodeGenOpts.StructPathTBAA)
354 llvm::MDNode *&N = AccessTagMetadataCache[Info];
360 assert(!Info.
Offset &&
"Nonzero offset for an access with no base type!");
362 if (CodeGenOpts.NewStructPathTBAA) {
383 if (!InfoA || !InfoB)
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Decl - This represents one declaration (or definition), e.g.
llvm::MDNode * AccessType
AccessType - The final access type.
The base class of the type hierarchy.
CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext)
const T * getAs() const
Member-template getAs<specific type>'.
RecordDecl - Represents a struct/union/class.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isStdByteType() const
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isReferenceType() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
bool isIncomplete() const
static bool isValidBaseType(QualType QTy)
Check if the given type is a valid base type to be used in access tags.
TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType)
getVTablePtrAccessInfo - Get the TBAA information that describes an access to a virtual table pointer...
field_iterator field_begin() const
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.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Exposes information about the current target.
static bool TypeHasMayAlias(QualType QTy)
field_iterator field_end() const
llvm::MDNode * getBaseTypeInfo(QualType QTy)
getBaseTypeInfo - Get metadata that describes the given base access type.
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo)
mergeTBAAInfoForCast - Get merged TBAA information for the purpose of type casts. ...
The l-value was considered opaque, so the alignment was determined from a type.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, TBAAAccessInfo InfoB)
mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the purpose of conditional oper...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
llvm::MDNode * BaseType
BaseType - The base/leading access type.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
uint64_t Size
Size - The size of access, in bytes.
llvm::MDNode * getTBAAStructInfo(QualType QTy)
getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of the given type...
bool hasFlexibleArrayMember() const
virtual void mangleTypeName(QualType T, raw_ostream &)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing...
llvm::MDNode * getTypeInfo(QualType QTy)
getTypeInfo - Get metadata used to describe accesses to objects of the given type.
Dataflow Directional Tag Classes.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Represents a C++ struct/union/class.
This class is used for builtin types like 'int'.
llvm::MDNode * getAccessTagInfo(TBAAAccessInfo Info)
getAccessTagInfo - Get TBAA tag for a given memory access.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
bool isPointerType() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
uint64_t Offset
Offset - The byte offset of the final access within the base one.
static TBAAAccessInfo getMayAliasInfo()