vsk updated this revision to Diff 221391.
vsk marked 3 inline comments as done.
vsk added a comment.
- Address latest review feedback.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D67774/new/
https://reviews.llvm.org/D67774
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/AST/Mangle.cpp
clang/lib/Sema/SemaDecl.cpp
clang/unittests/AST/DeclTest.cpp
lldb/source/Symbol/ClangASTContext.cpp
Index: lldb/source/Symbol/ClangASTContext.cpp
===================================================================
--- lldb/source/Symbol/ClangASTContext.cpp
+++ lldb/source/Symbol/ClangASTContext.cpp
@@ -8300,8 +8300,8 @@
cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
if (mangled_name != nullptr) {
- cxx_method_decl->addAttr(
- clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
+ cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
+ *getASTContext(), mangled_name, /*literal=*/true));
}
// Populate the method decl with parameter decls
Index: clang/unittests/AST/DeclTest.cpp
===================================================================
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -10,12 +10,16 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Mangle.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
using namespace clang::ast_matchers;
using namespace clang::tooling;
+using namespace clang;
TEST(Decl, CleansUpAPValues) {
MatchFinder Finder;
@@ -56,3 +60,49 @@
"constexpr _Complex __uint128_t c = 0xffffffffffffffff;",
Args));
}
+
+TEST(Decl, AsmLabelAttr) {
+ // Create two method decls: `f` and `g`.
+ StringRef Code = R"(
+ struct S {
+ void f() {}
+ void g() {}
+ };
+ )";
+ auto AST =
+ tooling::buildASTFromCodeWithArgs(Code, {"-target", "i386-apple-darwin"});
+ ASTContext &Ctx = AST->getASTContext();
+ DiagnosticsEngine &Diags = AST->getDiagnostics();
+ SourceManager &SM = AST->getSourceManager();
+ FileID MainFileID = SM.getMainFileID();
+
+ // Find the method decls within the AST.
+ SmallVector<Decl *, 1> Decls;
+ AST->findFileRegionDecls(MainFileID, Code.find('{'), 0, Decls);
+ ASSERT_TRUE(Decls.size() == 1);
+ CXXRecordDecl *DeclS = cast<CXXRecordDecl>(Decls[0]);
+ NamedDecl *DeclF = *DeclS->method_begin();
+ NamedDecl *DeclG = *(++DeclS->method_begin());
+
+ // Attach asm labels to the decls: one literal, and one subject to global
+ // prefixing.
+ DeclF->addAttr(::new (Ctx) AsmLabelAttr(Ctx, SourceLocation(), "foo",
+ /*LiteralLabel=*/true));
+ DeclG->addAttr(::new (Ctx) AsmLabelAttr(Ctx, SourceLocation(), "goo",
+ /*LiteralLabel=*/false));
+
+ // Mangle the decl names.
+ std::string MangleF, MangleG;
+ MangleContext *MC = ItaniumMangleContext::create(Ctx, Diags);
+ {
+ llvm::raw_string_ostream OS(MangleF);
+ MC->mangleName(DeclF, OS);
+ }
+ {
+ llvm::raw_string_ostream OS(MangleG);
+ MC->mangleName(DeclG, OS);
+ }
+
+ ASSERT_TRUE(0 == MangleF.compare("foo"));
+ ASSERT_TRUE(0 == MangleG.compare("\x01goo"));
+}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -2766,7 +2766,7 @@
if (AsmLabelAttr *NewA = New->getAttr<AsmLabelAttr>()) {
if (AsmLabelAttr *OldA = Old->getAttr<AsmLabelAttr>()) {
- if (OldA->getLabel() != NewA->getLabel()) {
+ if (!OldA->equivalent(NewA)) {
// This redeclaration changes __asm__ label.
Diag(New->getLocation(), diag::err_different_asm_label);
Diag(OldA->getLocation(), diag::note_previous_declaration);
@@ -6983,8 +6983,8 @@
}
}
- NewVD->addAttr(::new (Context)
- AsmLabelAttr(Context, SE->getStrTokenLoc(0), Label));
+ NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getStrTokenLoc(0),
+ Label, /*LiteralLabel=*/false));
} else if (!ExtnameUndeclaredIdentifiers.empty()) {
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -8882,8 +8882,9 @@
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getStrTokenLoc(0),
- SE->getString()));
+ NewFD->addAttr(::new (Context)
+ AsmLabelAttr(Context, SE->getStrTokenLoc(0),
+ SE->getString(), /*LiteralLabel=*/false));
} else if (!ExtnameUndeclaredIdentifiers.empty()) {
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
@@ -17555,8 +17556,8 @@
LookupOrdinaryName);
AttributeCommonInfo Info(AliasName, SourceRange(AliasNameLoc),
AttributeCommonInfo::AS_Pragma);
- AsmLabelAttr *Attr =
- AsmLabelAttr::CreateImplicit(Context, AliasName->getName(), Info);
+ AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit(
+ Context, AliasName->getName(), /*LiteralLabel=*/false, Info);
// If a declaration that:
// 1) declares a function or a variable
Index: clang/lib/AST/Mangle.cpp
===================================================================
--- clang/lib/AST/Mangle.cpp
+++ clang/lib/AST/Mangle.cpp
@@ -122,15 +122,21 @@
if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
// If we have an asm name, then we use it as the mangling.
+ // If the label is literal, or if this is an alias for an LLVM intrinsic,
+ // the global prefix must not be prepended.
+ if (ALA->getLiteralLabel() || ALA->getLabel().startswith("llvm.")) {
+ Out << ALA->getLabel();
+ return;
+ }
+
// Adding the prefix can cause problems when one file has a "foo" and
// another has a "\01foo". That is known to happen on ELF with the
// tricks normally used for producing aliases (PR9177). Fortunately the
// llvm mangler on ELF is a nop, so we can just avoid adding the \01
- // marker. We also avoid adding the marker if this is an alias for an
- // LLVM intrinsic.
+ // marker.
char GlobalPrefix =
getASTContext().getTargetInfo().getDataLayout().getGlobalPrefix();
- if (GlobalPrefix && !ALA->getLabel().startswith("llvm."))
+ if (GlobalPrefix)
Out << '\01'; // LLVM IR Marker for __asm("foo")
Out << ALA->getLabel();
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -2558,6 +2558,26 @@
}];
}
+def AsmLabelDocs : Documentation {
+ let Category = DocCatDecl;
+ let Content = [{
+This attribute can be added to a function or variable to specify its mangled name.
+
+For example (assuming, for convenience, that a "_" is usually prepended to C symbol names for the target):
+
+.. code-block:: c
+
+ int var1 asm("altvar") = 1; // "altvar" in symbol table.
+ int var2 = 1; // "_var2" in symbol table.
+
+ void func1(void) asm("altfunc");
+ void func1(void) {} // "altfunc" in symbol table.
+ void func2(void) {} // "_func2" in symbol table.
+
+Clang's implementation of this attribute is compatible with GCC's, `documented here <https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html>`_.
+ }];
+}
+
def EnumExtensibilityDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -722,9 +722,25 @@
def AsmLabel : InheritableAttr {
let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
- let Args = [StringArgument<"Label">];
+ let Args = [
+ // Label specifies the mangled name for the decl.
+ StringArgument<"Label">,
+
+ // LiteralLabel specifies whether Label is literal, i.e. spelled
+ // exactly as it must be in the final mangle, or not, in which case
+ // it may be subject to global prefixing.
+ //
+ // TODO: Make it possible to specify this in source.
+ BoolArgument<"LiteralLabel">
+ ];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [AsmLabelDocs];
+ let AdditionalMembers =
+[{
+bool equivalent(AsmLabelAttr *Other) const {
+ return getLabel() == Other->getLabel() && getLiteralLabel() == Other->getLiteralLabel();
+}
+}];
}
def Availability : InheritableAttr {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits