本文整理汇总了C++中SmallString::clear方法的典型用法代码示例。如果您正苦于以下问题:C++ SmallString::clear方法的具体用法?C++ SmallString::clear怎么用?C++ SmallString::clear使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SmallString
的用法示例。
在下文中一共展示了SmallString::clear方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: EmitClangCommentHTMLNamedCharacterReferences
void EmitClangCommentHTMLNamedCharacterReferences(RecordKeeper &Records,
raw_ostream &OS) {
std::vector<Record *> Tags = Records.getAllDerivedDefinitions("NCR");
std::vector<StringMatcher::StringPair> NameToUTF8;
SmallString<32> CLiteral;
for (std::vector<Record *>::iterator I = Tags.begin(), E = Tags.end();
I != E; ++I) {
Record &Tag = **I;
std::string Spelling = Tag.getValueAsString("Spelling");
uint64_t CodePoint = Tag.getValueAsInt("CodePoint");
CLiteral.clear();
CLiteral.append("return ");
if (!translateCodePointToUTF8(CodePoint, CLiteral)) {
SrcMgr.PrintMessage(Tag.getLoc().front(),
SourceMgr::DK_Error,
Twine("invalid code point"));
continue;
}
CLiteral.append(";");
StringMatcher::StringPair Match(Spelling, CLiteral.str());
NameToUTF8.push_back(Match);
}
emitSourceFileHeader("HTML named character reference to UTF-8 "
"translation", OS);
OS << "StringRef translateHTMLNamedCharacterReferenceToUTF8(\n"
" StringRef Name) {\n";
StringMatcher("Name", NameToUTF8, OS).Emit();
OS << " return StringRef();\n"
<< "}\n\n";
}
开发者ID:FreeBSDFoundation,项目名称:freebsd,代码行数:33,代码来源:ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
示例2: renderRegionMarkers
void SourceCoverageView::renderRegionMarkers(
raw_ostream &OS, ArrayRef<const coverage::CoverageSegment *> Segments) {
SmallString<32> Buffer;
raw_svector_ostream BufferOS(Buffer);
unsigned PrevColumn = 1;
for (const auto *S : Segments) {
if (!S->IsRegionEntry)
continue;
// Skip to the new region
if (S->Col > PrevColumn)
OS.indent(S->Col - PrevColumn);
PrevColumn = S->Col + 1;
BufferOS << S->Count;
StringRef Str = BufferOS.str();
// Trim the execution count
Str = Str.substr(0, std::min(Str.size(), (size_t)7));
PrevColumn += Str.size();
OS << '^' << Str;
Buffer.clear();
}
OS << "\n";
if (Options.Debug)
for (const auto *S : Segments)
errs() << "Marker at " << S->Line << ":" << S->Col << " = " << S->Count
<< (S->IsRegionEntry ? "\n" : " (pop)\n");
}
示例3: renderRegionMarkers
void SourceCoverageView::renderRegionMarkers(raw_ostream &OS,
ArrayRef<RegionMarker> Regions) {
SmallString<32> Buffer;
raw_svector_ostream BufferOS(Buffer);
unsigned PrevColumn = 1;
for (const auto &Region : Regions) {
// Skip to the new region
if (Region.Column > PrevColumn)
OS.indent(Region.Column - PrevColumn);
PrevColumn = Region.Column + 1;
BufferOS << Region.ExecutionCount;
StringRef Str = BufferOS.str();
// Trim the execution count
Str = Str.substr(0, std::min(Str.size(), (size_t)7));
PrevColumn += Str.size();
OS << '^' << Str;
Buffer.clear();
}
OS << "\n";
if (Options.Debug) {
for (const auto &Region : Regions) {
errs() << "Marker at " << Region.Line << ":" << Region.Column << " = "
<< Region.ExecutionCount << "\n";
}
}
}
示例4: emitLocalVariable
void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
// LocalSym record, see SymbolRecord.h for more info.
MCSymbol *LocalBegin = MMI->getContext().createTempSymbol(),
*LocalEnd = MMI->getContext().createTempSymbol();
OS.AddComment("Record length");
OS.emitAbsoluteSymbolDiff(LocalEnd, LocalBegin, 2);
OS.EmitLabel(LocalBegin);
OS.AddComment("Record kind: S_LOCAL");
OS.EmitIntValue(unsigned(SymbolRecordKind::S_LOCAL), 2);
uint16_t Flags = 0;
if (Var.DIVar->isParameter())
Flags |= LocalSym::IsParameter;
if (Var.DefRanges.empty())
Flags |= LocalSym::IsOptimizedOut;
OS.AddComment("TypeIndex");
OS.EmitIntValue(TypeIndex::Int32().getIndex(), 4);
OS.AddComment("Flags");
OS.EmitIntValue(Flags, 2);
// Truncate the name so we won't overflow the record length field.
emitNullTerminatedSymbolName(OS, Var.DIVar->getName());
OS.EmitLabel(LocalEnd);
// Calculate the on disk prefix of the appropriate def range record. The
// records and on disk formats are described in SymbolRecords.h. BytePrefix
// should be big enough to hold all forms without memory allocation.
SmallString<20> BytePrefix;
for (const LocalVarDefRange &DefRange : Var.DefRanges) {
BytePrefix.clear();
// FIXME: Handle bitpieces.
if (DefRange.StructOffset != 0)
continue;
if (DefRange.InMemory) {
DefRangeRegisterRelSym Sym{};
ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL);
Sym.BaseRegister = DefRange.CVRegister;
Sym.Flags = 0; // Unclear what matters here.
Sym.BasePointerOffset = DefRange.DataOffset;
BytePrefix +=
StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind));
BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
sizeof(Sym) - sizeof(LocalVariableAddrRange));
} else {
assert(DefRange.DataOffset == 0 && "unexpected offset into register");
DefRangeRegisterSym Sym{};
ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER);
Sym.Register = DefRange.CVRegister;
Sym.MayHaveNoName = 0; // Unclear what matters here.
BytePrefix +=
StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind));
BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
sizeof(Sym) - sizeof(LocalVariableAddrRange));
}
OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
}
}
示例5: AddPath
void InitHeaderSearch::AddPath(const Twine &Path,
IncludeDirGroup Group, bool isCXXAware,
bool isUserSupplied, bool isFramework,
bool IgnoreSysRoot) {
assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
FileManager &FM = Headers.getFileMgr();
// Compute the actual path, taking into consideration -isysroot.
SmallString<256> MappedPathStorage;
StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
// Handle isysroot.
if ((Group == System || Group == CXXSystem) && !IgnoreSysRoot &&
#if defined(_WIN32)
!MappedPathStr.empty() &&
llvm::sys::path::is_separator(MappedPathStr[0]) &&
#else
llvm::sys::path::is_absolute(MappedPathStr) &&
#endif
IsNotEmptyOrRoot) {
MappedPathStorage.clear();
MappedPathStr =
(IncludeSysroot + Path).toStringRef(MappedPathStorage);
}
// Compute the DirectoryLookup type.
SrcMgr::CharacteristicKind Type;
if (Group == Quoted || Group == Angled || Group == IndexHeaderMap)
Type = SrcMgr::C_User;
else if (isCXXAware)
Type = SrcMgr::C_System;
else
Type = SrcMgr::C_ExternCSystem;
// If the directory exists, add it.
if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) {
IncludePath.push_back(std::make_pair(Group, DirectoryLookup(DE, Type,
isUserSupplied, isFramework)));
return;
}
// Check to see if this is an apple-style headermap (which are not allowed to
// be frameworks).
if (!isFramework) {
if (const FileEntry *FE = FM.getFile(MappedPathStr)) {
if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
// It is a headermap, add it to the search path.
IncludePath.push_back(std::make_pair(Group, DirectoryLookup(HM, Type,
isUserSupplied, Group == IndexHeaderMap)));
return;
}
}
}
if (Verbose)
llvm::errs() << "ignoring nonexistent directory \""
<< MappedPathStr << "\"\n";
}
示例6: StringRef
ErrorOr<StringRef> ELFLinkingContext::searchLibrary(StringRef libName) const {
bool foundFile = false;
StringRef pathref;
SmallString<128> path;
for (StringRef dir : _inputSearchPaths) {
// Search for dynamic library
if (!_isStaticExecutable) {
path.clear();
if (dir.startswith("=/")) {
path.assign(_sysrootPath);
path.append(dir.substr(1));
} else {
path.assign(dir);
}
llvm::sys::path::append(path, Twine("lib") + libName + ".so");
pathref = path.str();
if (llvm::sys::fs::exists(pathref)) {
foundFile = true;
}
}
// Search for static libraries too
if (!foundFile) {
path.clear();
if (dir.startswith("=/")) {
path.assign(_sysrootPath);
path.append(dir.substr(1));
} else {
path.assign(dir);
}
llvm::sys::path::append(path, Twine("lib") + libName + ".a");
pathref = path.str();
if (llvm::sys::fs::exists(pathref)) {
foundFile = true;
}
}
if (foundFile)
return StringRef(*new (_allocator) std::string(pathref));
}
if (!llvm::sys::fs::exists(libName))
return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
return libName;
}
示例7: move
std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
SmallString<128> StringStorage;
if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
StringRef KeyStr = SN->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
KeyStr = StringStorage.str().copy(StringAllocator);
}
return llvm::make_unique<ScalarHNode>(N, KeyStr);
} else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
return llvm::make_unique<ScalarHNode>(N, ValueCopy);
} else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
auto SQHNode = llvm::make_unique<SequenceHNode>(N);
for (Node &SN : *SQ) {
auto Entry = createHNodes(&SN);
if (EC)
break;
SQHNode->Entries.push_back(std::move(Entry));
}
return std::move(SQHNode);
} else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
auto mapHNode = llvm::make_unique<MapHNode>(N);
for (KeyValueNode &KVN : *Map) {
Node *KeyNode = KVN.getKey();
ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
Node *Value = KVN.getValue();
if (!Key || !Value) {
if (!Key)
setError(KeyNode, "Map key must be a scalar");
if (!Value)
setError(KeyNode, "Map value must not be empty");
break;
}
StringStorage.clear();
StringRef KeyStr = Key->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
KeyStr = StringStorage.str().copy(StringAllocator);
}
auto ValueHNode = createHNodes(Value);
if (EC)
break;
mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
}
return std::move(mapHNode);
} else if (isa<NullNode>(N)) {
return llvm::make_unique<EmptyHNode>(N);
} else {
setError(N, "unknown node kind");
return nullptr;
}
}
示例8: applyScopeRestrictions
void LTOCodeGenerator::applyScopeRestrictions() {
if (ScopeRestrictionsDone)
return;
// Declare a callback for the internalize pass that will ask for every
// candidate GlobalValue if it can be internalized or not.
SmallString<64> MangledName;
auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
// Unnamed globals can't be mangled, but they can't be preserved either.
if (!GV.hasName())
return false;
// Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
// with the linker supplied name, which on Darwin includes a leading
// underscore.
MangledName.clear();
MangledName.reserve(GV.getName().size() + 1);
Mangler::getNameWithPrefix(MangledName, GV.getName(),
MergedModule->getDataLayout());
return MustPreserveSymbols.count(MangledName);
};
// Preserve linkonce value on linker request
preserveDiscardableGVs(*MergedModule, mustPreserveGV);
if (!ShouldInternalize)
return;
if (ShouldRestoreGlobalsLinkage) {
// Record the linkage type of non-local symbols so they can be restored
// prior
// to module splitting.
auto RecordLinkage = [&](const GlobalValue &GV) {
if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
GV.hasName())
ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
};
for (auto &GV : *MergedModule)
RecordLinkage(GV);
for (auto &GV : MergedModule->globals())
RecordLinkage(GV);
for (auto &GV : MergedModule->aliases())
RecordLinkage(GV);
}
// Update the llvm.compiler_used globals to force preserving libcalls and
// symbols referenced from asm
updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
internalizeModule(*MergedModule, mustPreserveGV);
ScopeRestrictionsDone = true;
}
示例9: ScalarHNode
Input::HNode *Input::createHNodes(Node *N) {
SmallString<128> StringStorage;
if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
StringRef KeyStr = SN->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
unsigned Len = StringStorage.size();
char *Buf = StringAllocator.Allocate<char>(Len);
memcpy(Buf, &StringStorage[0], Len);
KeyStr = StringRef(Buf, Len);
}
return new ScalarHNode(N, KeyStr);
} else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
SequenceHNode *SQHNode = new SequenceHNode(N);
for (Node &SN : *SQ) {
HNode *Entry = this->createHNodes(&SN);
if (EC)
break;
SQHNode->Entries.push_back(Entry);
}
return SQHNode;
} else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
MapHNode *mapHNode = new MapHNode(N);
for (KeyValueNode &KVN : *Map) {
Node *KeyNode = KVN.getKey();
ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KeyNode);
if (!KeyScalar) {
setError(KeyNode, "Map key must be a scalar");
break;
}
StringStorage.clear();
StringRef KeyStr = KeyScalar->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
unsigned Len = StringStorage.size();
char *Buf = StringAllocator.Allocate<char>(Len);
memcpy(Buf, &StringStorage[0], Len);
KeyStr = StringRef(Buf, Len);
}
HNode *ValueHNode = this->createHNodes(KVN.getValue());
if (EC)
break;
mapHNode->Mapping[KeyStr] = ValueHNode;
}
return mapHNode;
} else if (isa<NullNode>(N)) {
return new EmptyHNode(N);
} else {
setError(N, "unknown node kind");
return nullptr;
}
}
示例10: ScalarHNode
Input::HNode *Input::createHNodes(Node *N) {
SmallString<128> StringStorage;
if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
StringRef KeyStr = SN->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
unsigned Len = StringStorage.size();
char *Buf = StringAllocator.Allocate<char>(Len);
memcpy(Buf, &StringStorage[0], Len);
KeyStr = StringRef(Buf, Len);
}
return new ScalarHNode(N, KeyStr);
} else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
SequenceHNode *SQHNode = new SequenceHNode(N);
for (SequenceNode::iterator i = SQ->begin(), End = SQ->end(); i != End;
++i) {
HNode *Entry = this->createHNodes(i);
if (EC)
break;
SQHNode->Entries.push_back(Entry);
}
return SQHNode;
} else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
MapHNode *mapHNode = new MapHNode(N);
for (MappingNode::iterator i = Map->begin(), End = Map->end(); i != End;
++i) {
ScalarNode *KeyScalar = dyn_cast<ScalarNode>(i->getKey());
StringStorage.clear();
StringRef KeyStr = KeyScalar->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
unsigned Len = StringStorage.size();
char *Buf = StringAllocator.Allocate<char>(Len);
memcpy(Buf, &StringStorage[0], Len);
KeyStr = StringRef(Buf, Len);
}
HNode *ValueHNode = this->createHNodes(i->getValue());
if (EC)
break;
mapHNode->Mapping[KeyStr] = ValueHNode;
}
return mapHNode;
} else if (isa<NullNode>(N)) {
return new EmptyHNode(N);
} else {
setError(N, "unknown node kind");
return NULL;
}
}
示例11: computeRelativePath
/// \brief Compute the relative path that names the given file relative to
/// the given directory.
static void computeRelativePath(FileManager &FM, const DirectoryEntry *Dir,
const FileEntry *File,
SmallString<128> &Result) {
Result.clear();
StringRef FilePath = File->getDir()->getName();
StringRef Path = FilePath;
while (!Path.empty()) {
if (const DirectoryEntry *CurDir = FM.getDirectory(Path)) {
if (CurDir == Dir) {
Result = FilePath.substr(Path.size());
llvm::sys::path::append(Result,
llvm::sys::path::filename(File->getName()));
return;
}
}
Path = llvm::sys::path::parent_path(Path);
}
Result = File->getName();
}
示例12: linkDefinedTypeBodies
/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest
/// module from a type definition in the source module.
void TypeMapTy::linkDefinedTypeBodies() {
SmallVector<Type*, 16> Elements;
SmallString<16> TmpName;
// Note that processing entries in this loop (calling 'get') can add new
// entries to the SrcDefinitionsToResolve vector.
while (!SrcDefinitionsToResolve.empty()) {
StructType *SrcSTy = SrcDefinitionsToResolve.pop_back_val();
StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
// TypeMap is a many-to-one mapping, if there were multiple types that
// provide a body for DstSTy then previous iterations of this loop may have
// already handled it. Just ignore this case.
if (!DstSTy->isOpaque()) continue;
assert(!SrcSTy->isOpaque() && "Not resolving a definition?");
// Map the body of the source type over to a new body for the dest type.
Elements.resize(SrcSTy->getNumElements());
for (unsigned i = 0, e = Elements.size(); i != e; ++i)
Elements[i] = getImpl(SrcSTy->getElementType(i));
DstSTy->setBody(Elements, SrcSTy->isPacked());
// If DstSTy has no name or has a longer name than STy, then viciously steal
// STy's name.
if (!SrcSTy->hasName()) continue;
StringRef SrcName = SrcSTy->getName();
if (!DstSTy->hasName() || DstSTy->getName().size() > SrcName.size()) {
TmpName.insert(TmpName.end(), SrcName.begin(), SrcName.end());
SrcSTy->setName("");
DstSTy->setName(TmpName.str());
TmpName.clear();
}
}
DstResolvedOpaqueTypes.clear();
}
示例13: buildMSAsmString
// Build the unmodified AsmString used by the IR. Also build the individual
// asm instruction(s) and place them in the AsmStrings vector; these are fed
// to the AsmParser.
static std::string buildMSAsmString(Sema &SemaRef, ArrayRef<Token> AsmToks,
std::vector<std::string> &AsmStrings,
std::vector<std::pair<unsigned,unsigned> > &AsmTokRanges) {
assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
SmallString<512> Res;
SmallString<512> Asm;
unsigned startTok = 0;
for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
bool isNewAsm = i == 0 || AsmToks[i].isAtStartOfLine() ||
AsmToks[i].is(tok::kw_asm);
if (isNewAsm) {
if (i) {
AsmStrings.push_back(Asm.str());
AsmTokRanges.push_back(std::make_pair(startTok, i-1));
startTok = i;
Res += Asm;
Asm.clear();
Res += '\n';
}
if (AsmToks[i].is(tok::kw_asm)) {
i++; // Skip __asm
assert (i != e && "Expected another token");
}
}
if (i && AsmToks[i].hasLeadingSpace() && !isNewAsm)
Asm += ' ';
Asm += getSpelling(SemaRef, AsmToks[i]);
}
AsmStrings.push_back(Asm.str());
AsmTokRanges.push_back(std::make_pair(startTok, AsmToks.size()-1));
Res += Asm;
return Res.str();
}
示例14: os
//.........这里部分代码省略.........
verify(emitLoadOfAlignmentMask(IGF, layoutType),
getAlignmentMaskConstant(fixedTI->getFixedAlignment()),
"alignment mask");
verify(emitLoadOfStride(IGF, layoutType),
getSizeConstant(fixedTI->getFixedStride()),
"stride");
verify(emitLoadOfIsInline(IGF, layoutType),
getBoolConstant(fixedTI->getFixedPacking(IGF.IGM)
== FixedPacking::OffsetZero),
"is-inline bit");
verify(emitLoadOfIsPOD(IGF, layoutType),
getBoolConstant(fixedTI->isPOD(ResilienceExpansion::Maximal)),
"is-POD bit");
verify(emitLoadOfIsBitwiseTakable(IGF, layoutType),
getBoolConstant(fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal)),
"is-bitwise-takable bit");
unsigned xiCount = fixedTI->getFixedExtraInhabitantCount(IGF.IGM);
verify(emitLoadOfHasExtraInhabitants(IGF, layoutType),
getBoolConstant(xiCount != 0),
"has-extra-inhabitants bit");
// Check extra inhabitants.
if (xiCount > 0) {
verify(emitLoadOfExtraInhabitantCount(IGF, layoutType),
getSizeConstant(Size(xiCount)),
"extra inhabitant count");
// Verify that the extra inhabitant representations are consistent.
// TODO: Update for EnumPayload implementation changes.
#if 0
auto xiBuf = IGF.createAlloca(fixedTI->getStorageType(),
fixedTI->getFixedAlignment(),
"extra-inhabitant");
auto xiOpaque = IGF.Builder.CreateBitCast(xiBuf, IGF.IGM.OpaquePtrTy);
// TODO: Randomize the set of extra inhabitants we check.
unsigned bits = fixedTI->getFixedSize().getValueInBits();
for (unsigned i = 0, e = std::min(xiCount, 1024u);
i < e; ++i) {
// Initialize the buffer with junk, to help ensure we're insensitive to
// insignificant bits.
// TODO: Randomize the filler.
IGF.Builder.CreateMemSet(xiBuf.getAddress(),
llvm::ConstantInt::get(IGF.IGM.Int8Ty, 0x5A),
fixedTI->getFixedSize().getValue(),
fixedTI->getFixedAlignment().getValue());
// Ask the runtime to store an extra inhabitant.
auto index = llvm::ConstantInt::get(IGF.IGM.Int32Ty, i);
emitStoreExtraInhabitantCall(IGF, layoutType, index,
xiOpaque.getAddress());
// Compare the stored extra inhabitant against the fixed extra
// inhabitant pattern.
auto fixedXI = fixedTI->getFixedExtraInhabitantValue(IGF.IGM, bits, i);
auto xiBuf2 = IGF.Builder.CreateBitCast(xiBuf,
fixedXI->getType()->getPointerTo());
llvm::Value *runtimeXI = IGF.Builder.CreateLoad(xiBuf2);
runtimeXI = fixedTI->maskFixedExtraInhabitant(IGF, runtimeXI);
numberBuf.clear();
{
llvm::raw_svector_ostream os(numberBuf);
os << i;
os.flush();
}
verify(runtimeXI, fixedXI,
llvm::Twine("stored extra inhabitant ") + numberBuf.str());
// Now store the fixed extra inhabitant and ask the runtime to identify
// it.
// Mask in junk to make sure the runtime correctly ignores it.
auto xiMask = fixedTI->getFixedExtraInhabitantMask(IGF.IGM).asAPInt();
auto maskVal = llvm::ConstantInt::get(IGF.IGM.getLLVMContext(), xiMask);
auto notMaskVal
= llvm::ConstantInt::get(IGF.IGM.getLLVMContext(), ~xiMask);
// TODO: Randomize the filler.
auto xiFill = llvm::ConstantInt::getAllOnesValue(fixedXI->getType());
llvm::Value *xiFillMask = IGF.Builder.CreateAnd(notMaskVal, xiFill);
llvm::Value *xiValMask = IGF.Builder.CreateAnd(maskVal, fixedXI);
llvm::Value *filledXI = IGF.Builder.CreateOr(xiFillMask, xiValMask);
IGF.Builder.CreateStore(filledXI, xiBuf2);
auto runtimeIndex = emitGetExtraInhabitantIndexCall(IGF, layoutType,
xiOpaque.getAddress());
verify(runtimeIndex, index,
llvm::Twine("extra inhabitant index calculation ")
+ numberBuf.str());
}
#endif
}
// TODO: Verify interesting layout properties specific to the kind of type,
// such as struct or class field offsets, enum case tags, vtable entries,
// etc.
}
}
示例15: handleSymverAliases
// Ensure ELF .symver aliases get the same binding as the defined symbol
// they alias with.
static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
if (Streamer.symverAliases().empty())
return;
// The name in the assembler will be mangled, but the name in the IR
// might not, so we first compute a mapping from mangled name to GV.
Mangler Mang;
SmallString<64> MangledName;
StringMap<const GlobalValue *> MangledNameMap;
auto GetMangledName = [&](const GlobalValue &GV) {
if (!GV.hasName())
return;
MangledName.clear();
MangledName.reserve(GV.getName().size() + 1);
Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
MangledNameMap[MangledName] = &GV;
};
for (const Function &F : M)
GetMangledName(F);
for (const GlobalVariable &GV : M.globals())
GetMangledName(GV);
for (const GlobalAlias &GA : M.aliases())
GetMangledName(GA);
// Walk all the recorded .symver aliases, and set up the binding
// for each alias.
for (auto &Symver : Streamer.symverAliases()) {
const MCSymbol *Aliasee = Symver.first;
MCSymbolAttr Attr = MCSA_Invalid;
// First check if the aliasee binding was recorded in the asm.
RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
switch (state) {
case RecordStreamer::Global:
case RecordStreamer::DefinedGlobal:
Attr = MCSA_Global;
break;
case RecordStreamer::UndefinedWeak:
case RecordStreamer::DefinedWeak:
Attr = MCSA_Weak;
break;
default:
break;
}
// If we don't have a symbol attribute from assembly, then check if
// the aliasee was defined in the IR.
if (Attr == MCSA_Invalid) {
const auto *GV = M.getNamedValue(Aliasee->getName());
if (!GV) {
auto MI = MangledNameMap.find(Aliasee->getName());
if (MI != MangledNameMap.end())
GV = MI->second;
else
continue;
}
if (GV->hasExternalLinkage())
Attr = MCSA_Global;
else if (GV->hasLocalLinkage())
Attr = MCSA_Local;
else if (GV->isWeakForLinker())
Attr = MCSA_Weak;
}
if (Attr == MCSA_Invalid)
continue;
// Set the detected binding on each alias with this aliasee.
for (auto &Alias : Symver.second)
Streamer.EmitSymbolAttribute(Alias, Attr);
}
}