blob: 02c95c0dce497b8409f20a44b4bfad04fb5235f8 [file] [log] [blame]
Dan Gohman947c9af2010-10-14 23:06:10 +00001//===--- CodeGenTypes.cpp - TBAA information for LLVM CodeGen -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is the code that manages TBAA information.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenTBAA.h"
Dan Gohman2e29eb52010-10-15 20:23:12 +000015#include "Mangle.h"
Dan Gohman947c9af2010-10-14 23:06:10 +000016#include "clang/AST/ASTContext.h"
17#include "llvm/LLVMContext.h"
18#include "llvm/Metadata.h"
19using namespace clang;
20using namespace CodeGen;
21
22CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext,
Dan Gohman2e29eb52010-10-15 20:23:12 +000023 const LangOptions &Features, MangleContext &MContext)
24 : Context(Ctx), VMContext(VMContext), Features(Features), MContext(MContext),
25 Root(0), Char(0) {
Dan Gohman947c9af2010-10-14 23:06:10 +000026}
27
28CodeGenTBAA::~CodeGenTBAA() {
29}
30
Dan Gohman2e29eb52010-10-15 20:23:12 +000031llvm::MDNode *CodeGenTBAA::getTBAAInfoForNamedType(llvm::StringRef NameStr,
Dan Gohman947c9af2010-10-14 23:06:10 +000032 llvm::MDNode *Parent) {
33 llvm::Value *Ops[] = {
34 llvm::MDString::get(VMContext, NameStr),
35 Parent
36 };
37
38 return llvm::MDNode::get(VMContext, Ops, llvm::array_lengthof(Ops));
39}
40
41llvm::MDNode *
42CodeGenTBAA::getTBAAInfo(QualType QTy) {
43 Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
44
45 if (llvm::MDNode *N = MetadataCache[Ty])
46 return N;
47
48 if (!Root) {
49 Root = getTBAAInfoForNamedType("Experimental TBAA", 0);
50 Char = getTBAAInfoForNamedType("omnipotent char", Root);
51 }
52
53 // For now, just emit a very minimal tree.
Dan Gohman3f1cf0f2010-10-14 23:39:00 +000054 if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
Dan Gohman947c9af2010-10-14 23:06:10 +000055 switch (BTy->getKind()) {
Dan Gohmanf5c5e072010-10-15 17:52:03 +000056 // Character types are special and can alias anything.
57 // In C++, this technically only includes "char" and "unsigned char",
58 // and not "signed char". In C, it includes all three. For now,
Dan Gohman4a3b1b32010-10-15 20:24:10 +000059 // the risk of exploiting this detail in C++ seems likely to outweigh
Dan Gohmanf5c5e072010-10-15 17:52:03 +000060 // the benefit.
Dan Gohman947c9af2010-10-14 23:06:10 +000061 case BuiltinType::Char_U:
62 case BuiltinType::Char_S:
63 case BuiltinType::UChar:
64 case BuiltinType::SChar:
Dan Gohman947c9af2010-10-14 23:06:10 +000065 return Char;
Dan Gohman3f1cf0f2010-10-14 23:39:00 +000066
67 // Unsigned types can alias their corresponding signed types.
68 case BuiltinType::UShort:
69 return getTBAAInfo(Context.ShortTy);
70 case BuiltinType::UInt:
71 return getTBAAInfo(Context.IntTy);
72 case BuiltinType::ULong:
73 return getTBAAInfo(Context.LongTy);
74 case BuiltinType::ULongLong:
75 return getTBAAInfo(Context.LongLongTy);
76 case BuiltinType::UInt128:
77 return getTBAAInfo(Context.Int128Ty);
78
Dan Gohman2d0a3c72010-10-15 20:24:53 +000079 // Treat all other builtin types as distinct types. This includes
80 // treating wchar_t, char16_t, and char32_t as distinct from their
81 // "underlying types".
Dan Gohman947c9af2010-10-14 23:06:10 +000082 default:
83 return MetadataCache[Ty] =
84 getTBAAInfoForNamedType(BTy->getName(Features), Char);
85 }
86 }
87
Dan Gohmanc44fd642010-10-15 20:26:20 +000088 // TODO: Implement C++'s type "similarity" and consider dis-"similar"
89 // pointers distinct.
Dan Gohmand65c1962010-10-15 00:01:39 +000090 if (Ty->isPointerType())
Dan Gohmanc44fd642010-10-15 20:26:20 +000091 return MetadataCache[Ty] = getTBAAInfoForNamedType("any pointer", Char);
Dan Gohmand65c1962010-10-15 00:01:39 +000092
Dan Gohman2e29eb52010-10-15 20:23:12 +000093 // Enum types are distinct types. In C++ they have "underlying types",
94 // however they aren't related for TBAA.
95 if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
96 // In C mode, two anonymous enums are compatible iff their members
97 // are the same -- see C99 6.2.7p1. For now, be conservative. We could
98 // theoretically implement this by combining information about all the
99 // members into a single identifying MDNode.
100 if (!Features.CPlusPlus &&
101 ETy->getDecl()->getTypedefForAnonDecl())
102 return MetadataCache[Ty] = Char;
103
104 // In C++ mode, types have linkage, so we can rely on the ODR and
105 // on their mangled names, if they're external.
106 // TODO: Is there a way to get a program-wide unique name for a
107 // decl with local linkage or no linkage?
108 if (Features.CPlusPlus &&
109 ETy->getDecl()->getLinkage() != ExternalLinkage)
110 return MetadataCache[Ty] = Char;
111
112 // TODO: This is using the RTTI name. Is there a better way to get
113 // a unique string for a type?
114 llvm::SmallString<256> OutName;
115 MContext.mangleCXXRTTIName(QualType(ETy, 0), OutName);
116 return MetadataCache[Ty] = getTBAAInfoForNamedType(OutName, Char);
117 }
118
Dan Gohman3f1cf0f2010-10-14 23:39:00 +0000119 // For now, handle any other kind of type conservatively.
120 return MetadataCache[Ty] = Char;
Dan Gohman947c9af2010-10-14 23:06:10 +0000121}