Introduce SpecialCaseList::isIn overload for GlobalAliases.
authorPeter Collingbourne <peter@pcc.me.uk>
Mon, 19 Aug 2013 19:00:35 +0000 (19:00 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Mon, 19 Aug 2013 19:00:35 +0000 (19:00 +0000)
Differential Revision: http://llvm-reviews.chandlerc.com/D1437

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188688 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/SpecialCaseList.h
lib/Transforms/Utils/SpecialCaseList.cpp
unittests/Transforms/Utils/SpecialCaseList.cpp

index 90eace1aa0401663f37f0a60a896ef7e79c1790c..34c28fc1cafef72f6ac3779b52a53314f87e6450 100644 (file)
@@ -49,6 +49,7 @@
 
 namespace llvm {
 class Function;
+class GlobalAlias;
 class GlobalVariable;
 class MemoryBuffer;
 class Module;
@@ -79,6 +80,14 @@ class SpecialCaseList {
   bool isIn(const GlobalVariable &G,
             const StringRef Category = StringRef()) const;
 
+  /// Returns whether this global alias is listed in the given category, which
+  /// may be omitted to search the empty category.
+  ///
+  /// If GA aliases a function, the alias's name is matched as a function name
+  /// would be.  Similarly, aliases of globals are matched like globals.
+  bool isIn(const GlobalAlias &GA,
+            const StringRef Category = StringRef()) const;
+
   /// Returns whether this module is listed in the given category, which may be
   /// omitted to search the empty category.
   bool isIn(const Module &M, const StringRef Category = StringRef()) const;
index cf12bbfe3d7a8c9b8d083486d71041382ca642e8..2ef692c564c665cb07b05b9062f3e66accf29b33 100644 (file)
@@ -174,7 +174,7 @@ bool SpecialCaseList::isIn(const Function& F, const StringRef Category) const {
          inSectionCategory("fun", F.getName(), Category);
 }
 
-static StringRef GetGVTypeString(const GlobalVariable &G) {
+static StringRef GetGlobalTypeString(const GlobalValue &G) {
   // Types of GlobalVariables are always pointer types.
   Type *GType = G.getType()->getElementType();
   // For now we support blacklisting struct types only.
@@ -189,7 +189,19 @@ bool SpecialCaseList::isIn(const GlobalVariable &G,
                            const StringRef Category) const {
   return isIn(*G.getParent(), Category) ||
          inSectionCategory("global", G.getName(), Category) ||
-         inSectionCategory("type", GetGVTypeString(G), Category);
+         inSectionCategory("type", GetGlobalTypeString(G), Category);
+}
+
+bool SpecialCaseList::isIn(const GlobalAlias &GA,
+                           const StringRef Category) const {
+  if (isIn(*GA.getParent(), Category))
+    return true;
+
+  if (isa<FunctionType>(GA.getType()->getElementType()))
+    return inSectionCategory("fun", GA.getName(), Category);
+
+  return inSectionCategory("global", GA.getName(), Category) ||
+         inSectionCategory("type", GetGlobalTypeString(GA), Category);
 }
 
 bool SpecialCaseList::isIn(const Module &M, const StringRef Category) const {
index 92a730d5992d90fdadc87c9a011ef92f38d9c1e9..07ac908caabcc528f63785e1875a9e069c32d437 100644 (file)
@@ -34,6 +34,11 @@ protected:
         M, ST, false, GlobalValue::ExternalLinkage, 0, Name);
   }
 
+  GlobalAlias *makeAlias(StringRef Name, GlobalValue *Aliasee) {
+    return new GlobalAlias(Aliasee->getType(), GlobalValue::ExternalLinkage,
+                           Name, Aliasee, Aliasee->getParent());
+  }
+
   SpecialCaseList *makeSpecialCaseList(StringRef List, std::string &Error) {
     OwningPtr<MemoryBuffer> MB(MemoryBuffer::getMemBuffer(List));
     return SpecialCaseList::create(MB.get(), Error);
@@ -145,10 +150,48 @@ TEST_F(SpecialCaseListTest, GlobalIsIn) {
   EXPECT_TRUE(SCL->isIn(*Bar, "init"));
 }
 
+TEST_F(SpecialCaseListTest, AliasIsIn) {
+  Module M("hello", Ctx);
+  Function *Foo = makeFunction("foo", M);
+  GlobalVariable *Bar = makeGlobal("bar", "t", M);
+  GlobalAlias *FooAlias = makeAlias("fooalias", Foo);
+  GlobalAlias *BarAlias = makeAlias("baralias", Bar);
+
+  OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("fun:foo\n"));
+  EXPECT_FALSE(SCL->isIn(*FooAlias));
+  EXPECT_FALSE(SCL->isIn(*BarAlias));
+
+  SCL.reset(makeSpecialCaseList("global:bar\n"));
+  EXPECT_FALSE(SCL->isIn(*FooAlias));
+  EXPECT_FALSE(SCL->isIn(*BarAlias));
+
+  SCL.reset(makeSpecialCaseList("global:fooalias\n"));
+  EXPECT_FALSE(SCL->isIn(*FooAlias));
+  EXPECT_FALSE(SCL->isIn(*BarAlias));
+
+  SCL.reset(makeSpecialCaseList("fun:fooalias\n"));
+  EXPECT_TRUE(SCL->isIn(*FooAlias));
+  EXPECT_FALSE(SCL->isIn(*BarAlias));
+
+  SCL.reset(makeSpecialCaseList("global:baralias=init\n"));
+  EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
+  EXPECT_TRUE(SCL->isIn(*BarAlias, "init"));
+
+  SCL.reset(makeSpecialCaseList("type:t=init\n"));
+  EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
+  EXPECT_TRUE(SCL->isIn(*BarAlias, "init"));
+
+  SCL.reset(makeSpecialCaseList("fun:baralias=init\n"));
+  EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
+  EXPECT_FALSE(SCL->isIn(*BarAlias, "init"));
+}
+
 TEST_F(SpecialCaseListTest, Substring) {
   Module M("othello", Ctx);
   Function *F = makeFunction("tomfoolery", M);
   GlobalVariable *GV = makeGlobal("bartender", "t", M);
+  GlobalAlias *GA1 = makeAlias("buffoonery", F);
+  GlobalAlias *GA2 = makeAlias("foobar", GV);
 
   OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("src:hello\n"
                                                      "fun:foo\n"
@@ -156,9 +199,12 @@ TEST_F(SpecialCaseListTest, Substring) {
   EXPECT_FALSE(SCL->isIn(M));
   EXPECT_FALSE(SCL->isIn(*F));
   EXPECT_FALSE(SCL->isIn(*GV));
+  EXPECT_FALSE(SCL->isIn(*GA1));
+  EXPECT_FALSE(SCL->isIn(*GA2));
 
   SCL.reset(makeSpecialCaseList("fun:*foo*\n"));
   EXPECT_TRUE(SCL->isIn(*F));
+  EXPECT_TRUE(SCL->isIn(*GA1));
 }
 
 TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {