[llvm-dev] Why hasExternalLinkage() is not true for an external variable?

Peng Yu via llvm-dev llvm-dev at lists.llvm.org
Fri Jan 18 08:57:54 PST 2019


Hi,

I am trying to test whether an operand is external or not (code is
shown below). The variable "U" should be a global variable. But
hasExternalLinkage() returns 0 for it. Why is it so?

How to only keep  global variables (note that global functions are
also shown)? Thanks

$ clang++ -std=c++11 -fno-rtti -Wall -pedantic -I$HOME/llvm/include
-fPIC -c -o fun2var.o fun2var.cpp
$ clang fun2var.o '-Wl,-flat_namespace' '-Wl,-undefined'
'-Wl,suppress' -shared -o ./libfun2var.so
$ opt -load libfun2var.so -fun2var < hello.exe.0.0.preopt.bc 2>&1 1>/dev/null
main    u    1    0
main    u    1    0
main    f    0    1
f    llvm.dbg.declare    0    1
f    U    0    0
f    U    0    0
f    u.3    1    0
f    u.3    1    0

==> fun2var.cpp <==
/* vim: set noexpandtab tabstop=2: */
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include <llvm/IR/DebugLoc.h>
#include <llvm/IR/DebugInfoMetadata.h>
using namespace llvm;

namespace {
    // fun2var - The first implementation, without getAnalysisUsage.
    struct fun2var : public FunctionPass {
        static char ID; // Pass identification, replacement for typeid
        fun2var() : FunctionPass(ID) {}

        bool runOnFunction(Function &F) override {
            for (Instruction &I: instructions(F)) {
                for (Use &U: I.operands()) {
                    if(isa<GlobalValue>(U)) {
                        auto GV = dyn_cast<GlobalValue>(U);
                        errs() << F.getName() << '\t' << U->getName()
<< '\t' << GV->hasInternalLinkage() << '\t' <<
GV->hasExternalLinkage() << "\n";
                    }
                }
            }
            return false;
        }
    };
}

char fun2var::ID = 0;
static RegisterPass<fun2var> X("fun2var", "fun2var Pass");

$ clang -g -flto -std=gnu99 -Wall -pedantic -c -o hello.o hello.c
$ clang -g -flto -std=gnu99 -Wall -pedantic -c -o f.o f.c
$ clang hello.o f.o -flto -fuse-ld=gold '-Wl,-plugin-opt=save-temps'
-o hello.exe
==> f.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

int U;
static int u;

void f(int i) {
    U+=i;
    u+=i;
}

==> hello.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

extern int U;
static int u;

void f(int i);

int main() {
  ++u;
  f(10);
  return 0;
}

-- 
Regards,
Peng


More information about the llvm-dev mailing list