From ea266cad53e3d49771fa38103913d3ec7a166694 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Mon, 10 Jun 2013 20:45:12 +0000
Subject: Vendor import of clang tags/RELEASE_33/final r183502 (effectively,
 3.3 release):
 http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502

---
 lib/CodeGen/CodeGenTBAA.cpp | 82 +++++++++++++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 22 deletions(-)

(limited to 'lib/CodeGen/CodeGenTBAA.cpp')

diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
index 7e4d34a..5ff1560 100644
--- a/lib/CodeGen/CodeGenTBAA.cpp
+++ b/lib/CodeGen/CodeGenTBAA.cpp
@@ -50,13 +50,25 @@ llvm::MDNode *CodeGenTBAA::getRoot() {
   return Root;
 }
 
+// For struct-path aware TBAA, the scalar type has the same format as
+// the struct type: name, offset, pointer to another node in the type DAG.
+// For scalar TBAA, the scalar type is the same as the scalar tag:
+// name and a parent pointer.
+llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name,
+                                                llvm::MDNode *Parent) {
+  if (CodeGenOpts.StructPathTBAA)
+    return MDHelper.createTBAAScalarTypeNode(Name, Parent);
+  else
+    return MDHelper.createTBAANode(Name, Parent);
+}
+
 llvm::MDNode *CodeGenTBAA::getChar() {
   // Define the root of the tree for user-accessible memory. C and C++
   // give special powers to char and certain similar types. However,
   // these special powers only cover user-accessible memory, and doesn't
   // include things like vtables.
   if (!Char)
-    Char = MDHelper.createTBAANode("omnipotent char", getRoot());
+    Char = createTBAAScalarType("omnipotent char", getRoot());
 
   return Char;
 }
@@ -124,7 +136,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) {
     // "underlying types".
     default:
       return MetadataCache[Ty] =
-        MDHelper.createTBAANode(BTy->getName(Features), getChar());
+        createTBAAScalarType(BTy->getName(Features), getChar());
     }
   }
 
@@ -132,8 +144,8 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) {
   // TODO: Implement C++'s type "similarity" and consider dis-"similar"
   // pointers distinct.
   if (Ty->isPointerType())
-    return MetadataCache[Ty] = MDHelper.createTBAANode("any pointer",
-                                                       getChar());
+    return MetadataCache[Ty] = createTBAAScalarType("any pointer",
+                                                    getChar());
 
   // Enum types are distinct types. In C++ they have "underlying types",
   // however they aren't related for TBAA.
@@ -160,7 +172,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) {
     llvm::raw_svector_ostream Out(OutName);
     MContext.mangleCXXRTTIName(QualType(ETy, 0), Out);
     Out.flush();
-    return MetadataCache[Ty] = MDHelper.createTBAANode(OutName, getChar());
+    return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar());
   }
 
   // For now, handle any other kind of type conservatively.
@@ -168,7 +180,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) {
 }
 
 llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() {
-  return MDHelper.createTBAANode("vtable pointer", getRoot());
+  return createTBAAScalarType("vtable pointer", getRoot());
 }
 
 bool
@@ -192,8 +204,18 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
     unsigned idx = 0;
+    const FieldDecl *LastFD = 0;
+    bool IsMsStruct = RD->isMsStruct(Context);
     for (RecordDecl::field_iterator i = RD->field_begin(),
          e = RD->field_end(); i != e; ++i, ++idx) {
+      if (IsMsStruct) {
+        // Zero-length bitfields following non-bitfield members are ignored.
+        if (Context.ZeroBitfieldFollowsNonBitfield(*i, LastFD)) {
+          --idx;
+          continue;
+        }
+        LastFD = *i;
+      }
       uint64_t Offset = BaseOffset +
                         Layout.getFieldOffset(idx) / Context.getCharWidth();
       QualType FieldQTy = i->getType();
@@ -208,7 +230,9 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
   uint64_t Offset = BaseOffset;
   uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
   llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTBAAInfo(QTy);
-  Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAAInfo));
+  llvm::MDNode *TBAATag = CodeGenOpts.StructPathTBAA ?
+                          getTBAAScalarTagInfo(TBAAInfo) : TBAAInfo;
+  Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
   return true;
 }
 
@@ -231,9 +255,11 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
 static bool isTBAAPathStruct(QualType QTy) {
   if (const RecordType *TTy = QTy->getAs<RecordType>()) {
     const RecordDecl *RD = TTy->getDecl()->getDefinition();
+    if (RD->hasFlexibleArrayMember())
+      return false;
     // RD can be struct, union, class, interface or enum.
-    // For now, we only handle struct.
-    if (RD->isStruct() && !RD->hasFlexibleArrayMember())
+    // For now, we only handle struct and class.
+    if (RD->isStruct() || RD->isClass())
       return true;
   }
   return false;
@@ -251,29 +277,31 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {
     const RecordDecl *RD = TTy->getDecl()->getDefinition();
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
-    SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields;
-    // To reduce the size of MDNode for a given struct type, we only output
-    // once for all the fields with the same scalar types.
-    // Offsets for scalar fields in the type DAG are not used.
-    llvm::SmallSet <llvm::MDNode*, 4> ScalarFieldTypes;
+    SmallVector <std::pair<llvm::MDNode*, uint64_t>, 4> Fields;
     unsigned idx = 0;
+    const FieldDecl *LastFD = 0;
+    bool IsMsStruct = RD->isMsStruct(Context);
     for (RecordDecl::field_iterator i = RD->field_begin(),
          e = RD->field_end(); i != e; ++i, ++idx) {
+      if (IsMsStruct) {
+        // Zero-length bitfields following non-bitfield members are ignored.
+        if (Context.ZeroBitfieldFollowsNonBitfield(*i, LastFD)) {
+          --idx;
+          continue;
+        }
+        LastFD = *i;
+      }
+
       QualType FieldQTy = i->getType();
       llvm::MDNode *FieldNode;
       if (isTBAAPathStruct(FieldQTy))
         FieldNode = getTBAAStructTypeInfo(FieldQTy);
-      else {
+      else
         FieldNode = getTBAAInfo(FieldQTy);
-        // Ignore this field if the type already exists.
-        if (ScalarFieldTypes.count(FieldNode))
-          continue;
-        ScalarFieldTypes.insert(FieldNode);
-       }
       if (!FieldNode)
         return StructTypeMetadataCache[Ty] = NULL;
       Fields.push_back(std::make_pair(
-          Layout.getFieldOffset(idx) / Context.getCharWidth(), FieldNode));
+          FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth()));
     }
 
     // TODO: This is using the RTTI name. Is there a better way to get
@@ -305,8 +333,18 @@ CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,
   if (isTBAAPathStruct(BaseQTy))
     BNode  = getTBAAStructTypeInfo(BaseQTy);
   if (!BNode)
-    return StructTagMetadataCache[PathTag] = AccessNode;
+    return StructTagMetadataCache[PathTag] =
+       MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0);
 
   return StructTagMetadataCache[PathTag] =
     MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset);
 }
+
+llvm::MDNode *
+CodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) {
+  if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode])
+    return N;
+
+  return ScalarTagMetadataCache[AccessNode] =
+    MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0);
+}
-- 
cgit v1.1