标签: llvm-clang

如何在clang ++中禁用自动"通过指针传递"优化?

我有一个功能

void X(Object o)
{
 ....
}
Run Code Online (Sandbox Code Playgroud)

当我编译它时,我看到,该clang将其签名更改为

void X(Object* o)
Run Code Online (Sandbox Code Playgroud)

这很不方便,因为我直接从一些llvm IR代码中使用这个函数.如何禁止它进行此优化?

编辑:最小的工作示例:

#include <stdio.h>

class Object
{
public:
    Object();
    ~Object();
    int* pointer;
};

void Function(Object o)
{
    o.pointer = 0;
}

int main()
{
    Object a;
    Function(a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

通过以下命令行:

clang++ tst.cpp -emit-llvm -O0 tst.cpp -S -std=c++11
Run Code Online (Sandbox Code Playgroud)

Function被翻译成:

define void @_Z8Function6Object(%class.Object* %o) nounwind uwtable {
  %1 = getelementptr inbounds %class.Object* %o, i32 0, i32 0
  store i32* null, i32** %1, align 8
  ret void …
Run Code Online (Sandbox Code Playgroud)

c++ clang compiler-optimization llvm-clang clang++

8
推荐指数
1
解决办法
787
查看次数

Clang -Wweak-vtables和纯抽象类

关于此主题的先前问题:

这是我最近提出的问题的后续跟进: clang:没有外线虚拟方法定义(纯抽象C++类) ,并且被标记为此问题的副本:clang的-Wweak-含义是什么?虚函数表?.我不认为那回答了我的问题,所以在这里我专注于困扰我的事情,但尚未得到回答.

我的情景:

我正在尝试使用Clang-3.5编译以下简单的C++代码:

test.h:

class A
{
  public:
    A();
    virtual ~A() = 0;
};
Run Code Online (Sandbox Code Playgroud)

test.cc

#include "test.h"

A::A() {;}
A::~A() {;}
Run Code Online (Sandbox Code Playgroud)

我用来编译它的命令(Linux,uname -r:3.16.0-4-amd64):

$clang-3.5 -Wweak-vtables -std=c++11 -c test.cc
Run Code Online (Sandbox Code Playgroud)

而我得到的错误:

./test.h:1:7: warning: 'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit [-Wweak-vtables]
Run Code Online (Sandbox Code Playgroud)

当A类不是纯抽象时,上面的代码构建得很好.以下代码不会发出警告,唯一的变化是A类不再是抽象的:

test2.h:

class A
{
  public:
    A();
    virtual ~A();
};
Run Code Online (Sandbox Code Playgroud)

test2.cc

#include "test2.h"

A::A() {;}
A::~A() {;}
Run Code Online (Sandbox Code Playgroud)

我的问题

上面的代码在Clang中触发警告的纯抽象类有什么特别之处?

c++ abstract-class clang llvm-clang clang++

8
推荐指数
1
解决办法
3103
查看次数

Objective-C中的扩展问题

以下是处理类扩展的代码段.我要做的是生成一个称为内部ID的随机ID(稍后由程序使用),它以加密形式存储在内存中.代码无法使用gcc和clang编译(我在Windows上通过GNUStep运行Objective C),每个编译器都有不同的错误消息,在代码中作为注释提到.

请注意,我知道这个问题可以通过忽略主@faceface(即#import语句之后的那个)本身的扩展和声明方法和属性来轻松解决.我使用扩展的唯一原因是这个类是由一些其他子类继承的,"internalID"属性必须是不可访问的.

#import <Foundation/Foundation.h>

@interface Foo : NSObject
{
    NSString * idStr;
}
- (void)setInternalID;
- (NSString *)fetchExternalID;
@end

// Extension declaration
@interface Foo()
{ // Compilation via gcc throws error at this line stating "Expected identifier or '(' before '{' token"
    NSString *internalID; // Compilation via clang throws error at this line stating "instance variables may not be placed in class extension"
}
@end

@implementation Foo
- (void)setInternalID{
    internalID = [NSString stringWithFormat: 
    @"__KEY__INTERNAL__DUMP2872167841398551___8765%d98KLPYFGF(&^$#ESFK___JNHGV",arc4random()%100];
}
- (NSString *)fetchExternalID{
    NSString …
Run Code Online (Sandbox Code Playgroud)

gcc objective-c gnustep llvm-clang class-extensions

8
推荐指数
1
解决办法
234
查看次数

无法使用clang交叉编译到SPARC

所以情况就是这样:我需要能够从Linux机器(在Ubuntu上,它的价值)编译二进制文件,它们能够从SPARC服务器运行.我正在尝试编译的程序非常简单:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Testing the SPARC program...");
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试了许多不同的编译行来使它工作,但不幸的是似乎没有任何工作.

我试过传统的:

 clang -target sparc blah.c -o blahsparc
Run Code Online (Sandbox Code Playgroud)

但这不起作用,有一堆汇编程序失败:

 /tmp/blah-519e77.s: Assembler messages:
 /tmp/blah-519e77.s:7: Error: unknown pseudo-op: '.register'
 /tmp/blah-519e77.s:8: Error: unknown pseudo-op: '.register'
 /tmp/blah-519e77.s:9: Error: unknown pseudo-op: '.register'
 /tmp/blah-519e77.s:10: Error: unknown pseudo-op: '.register'
 /tmp/blah-519e77.s:11: Error: no such instruction: 'save %sp,-240,%sp'
 /tmp/blah-519e77.s:12: Error: no such instruction: 'st %g0, [%fp+2043]'
 ...
 clang: error: assembler (via gcc) command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

我也试过这个: …

c c++ sparc clang llvm-clang

7
推荐指数
1
解决办法
1506
查看次数

无法强制clang CompilerInstance对象将标头解析为C++文件

我有一个名为class.h的C++标头,我要解析:

class MyClass
{
  public:
    Class() {}
    ~Class() {}
    bool isTrue() const;
    bool isFalse() const;
  private:
    bool m_attrib;
};

bool MyClass::isTrue() const
{
  return true;
}
bool MyClass::isFalse() const
{
  return false;
}
Run Code Online (Sandbox Code Playgroud)

我使用clang编译器实例和AST使用者.我的所有代码都适用于c源文件.但我无法配置/强制CompilerInstance必须使用的语言.这是我使用的代码:

m_ci = new clang::CompilerInstance();
/*configure the langage to use*/
clang::CompilerInvocation *invocation = new clang::CompilerInvocation;
clang::LangOptions langOpts;
/*with langage = clang::IK_CXX*/
langOpts.CPlusPlus = 1; 
invocation->setLangDefaults(langOpts, langage);
m_ci->setInvocation(invocation);
m_ci->createDiagnostics();
llvm::IntrusiveRefCntPtr<clang::TargetOptions> pto( new clang::TargetOptions());
pto->Triple = llvm::sys::getDefaultTargetTriple();
clang::TargetInfo *pti = clang::TargetInfo::CreateTargetInfo(m_ci->getDiagnostics(), pto.getPtr());
m_ci->setTarget(pti);
m_ci->createFileManager();
m_ci->createSourceManager(ci->getFileManager());
m_ci->createPreprocessor();
/*add …
Run Code Online (Sandbox Code Playgroud)

c++ clang llvm-clang

7
推荐指数
1
解决办法
709
查看次数

FunctionPass中的LLVM LoopInfo无法编译

我开始学习llvm api,我写了第一遍.我的目标是打印函数如何调用彼此.

最近我想在显示屏上添加一些循环信息,以查看函数是否可以多次调用.但是当我尝试使用LoopInfo时,我得到了这个编译错误:

llvm[0]: Compiling cfg.cpp for Debug+Asserts build (PIC)
In file included from cfg.cpp:19:
In file included from /home/llvm-lab/llvm/include/llvm/Pass.h:378:
  /home/llvm-lab/llvm/include/llvm/PassAnalysisSupport.h:56:37: error:
        no member named 'ID' in 'llvm::LoopInfo'
      return addRequiredID(PassClass::ID);
                                  ^
cfg.cpp:33:10: note: in instantiation of function template
      specialization 'llvm::AnalysisUsage::addRequired<llvm::LoopInfo>'
      requested here
      AU.addRequired<LoopInfo>();
         ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "iostream"
#include "llvm/Pass.h"
#include "llvm/IR/InstIterator.h"
#include <llvm/IR/Instructions.h>
#include <llvm/Analysis/LoopInfo.h>

using namespace llvm;


namespace {
  struct CFG : public FunctionPass {
    static char ID; // Pass …
Run Code Online (Sandbox Code Playgroud)

llvm llvm-clang

7
推荐指数
1
解决办法
2150
查看次数

使用swift编译器裸机?

我真的很想使用swift进行嵌入式编程,因为我觉得它更适合用于c ++,我使用的处理器是ARM​​ Cortex-M4F(http://www.ti.com/tool/ek-tm4c123gxl)).看一下swift编译器页面,它说你可以从swift源生成LLVM IR然后我希望与LLVM交叉编译.这可能吗?

arm llvm llvm-clang llvm-ir swift

7
推荐指数
1
解决办法
1929
查看次数

什么是正确的 LLVM 标头保护样式?

在 clang tidy 中,检查[llvm-header-guard]查找 LLVM 样式的头保护,但我找不到任何正确的 LLVM 头保护样式的示例,特别是给定名称的结构,编码标准页面没有提到任何东西。

c++ include-guards llvm llvm-clang clang-tidy

7
推荐指数
1
解决办法
6570
查看次数

如何使用 clang 从行号获取源文本?

我正在使用 clang matcher 来获取结果节点。从结果节点中,我能够获取行号,假设为 17。现在,我想获取该行中的整个源代码。请帮忙。

让我详细解释一下。我有一个 clang 匹配器,可以在源代码中查找浮动文字。例如,第17行sr = 2.0 * rt_urand_Upu32_Yd_f_pw_snf(u);是源代码,那么它匹配2.0。这是我的匹配器:

const auto PA = floatLiteral(
                                isExpansionInMainFile(), 
                                unless(hasAncestor(arraySubscriptExpr()))
                            ).bind("pa");
            MatchFinder MatchFinder;
            MatchFinder.addMatcher(PA, &Handler);
            MatchFinder.matchAST(Context);
Run Code Online (Sandbox Code Playgroud)

从匹配器中,我可以获得匹配的节点。我能够检索行号(第 17 行)和列号(6)。请在下面找到我的代码:

const clang::FloatingLiteral* Variable = Result.Nodes.getNodeAs<clang::FloatingLiteral>("pa");
clang::SourceRange loc = Variable16->getSourceRange();
locStart = srcMgr.getPresumedLoc(loc.getBegin());
locEnd = srcMgr.getPresumedLoc(loc.getEnd());
std::cout << locStart.getLine()<< ":" << locEnd.getLine() << std::endl;
std::cout << locStart.getColumn() <<":" << locEnd.getColumn() << std::endl;
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试检索源代码,我只能得到部分数据。在网上做了一些研究后,我尝试通过两种方式检索源代码。第一种方法是使用词法分析器,请找到下面的代码:

llvm::StringRef ref = Lexer::getSourceText(CharSourceRange::getCharRange(statement->getSourceRange()), srcMgr, LangOptions());
cout << ref.str() << endl;
Run Code Online (Sandbox Code Playgroud)

第二种方法是使用重写器,请找到下面的代码:

clang::Rewriter rewriter;
rewriter.setSourceMgr(Result.Context->getSourceManager(),Result.Context->getLangOpts());
cout<<rewriter.getRewrittenText (loc)<<endl;
Run Code Online (Sandbox Code Playgroud)

据我了解,我似乎需要从第 …

clang llvm-clang clang-ast-matchers

7
推荐指数
1
解决办法
2018
查看次数

由于 MemorySanitizer 警告,使用 MemorySanitizer 工具构建 libc++ 失败

我正在尝试使用 MemorySanitizer 工具构建 libc++,以便我可以使用 MemorySanitizer 构建自己的项目。我在 Ubuntu 16.04 上使用 Clang 8.01。

我按照此处给出的说明进行操作,但构建最初因链接器错误而失败。我通过使用 lld 而不是默认链接器更正了链接器错误。然而,由于 MemorySanitizer 警告,构建失败了:

[  0%] Built target LLVMDemangle
[  4%] Built target LLVMSupport
[  4%] Built target LLVMTableGen
[  5%] Built target obj.llvm-tblgen
[  5%] Built target llvm-tblgen
[  5%] Building AttributesCompatFunc.inc...
==6384==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x51ee14 in _M_lower_bound /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:1940:7
    #1 0x51ee14 in find /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:2566
    #2 0x51ee14 in find /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_map.h:1194
    #3 0x51ee14 in llvm::RecordKeeper::getClass(llvm::StringRef) const /opt/llvm/llvm-801/include/llvm/TableGen/Record.h:1612
    #4 0xa2ff5c in llvm::TGParser::ParseClass() /opt/llvm/llvm-801/lib/TableGen/TGParser.cpp:2648:28
    #5 0xa2fceb in llvm::TGParser::ParseObject(llvm::MultiClass*) /opt/llvm/llvm-801/lib/TableGen/TGParser.cpp:3010:12 …
Run Code Online (Sandbox Code Playgroud)

llvm llvm-clang libc++ msan

7
推荐指数
1
解决办法
832
查看次数