leonardchan updated this revision to Diff 163604.
leonardchan marked 8 inline comments as done.
leonardchan added a comment.
- Removed default value for `getAttributedType` and added any macro identifier
necessary as a fourth argument to `getAttributedType`
- Added tracking for `LateAttr`s to keep any found macro identifier, although I
don't quite know how I can test this in the same fashion that I test with
`address_space` since it doesn't get printed in the type.
Repository:
rC Clang
https://reviews.llvm.org/D51329
Files:
include/clang/AST/ASTContext.h
include/clang/AST/Type.h
include/clang/Parse/Parser.h
include/clang/Sema/ParsedAttr.h
lib/AST/ASTContext.cpp
lib/AST/ASTDiagnostic.cpp
lib/AST/ASTImporter.cpp
lib/AST/Type.cpp
lib/AST/TypePrinter.cpp
lib/Parse/ParseDecl.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaObjCProperty.cpp
lib/Sema/SemaType.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/Sema/address_space_print_macro.c
test/Sema/address_spaces.c
Index: test/Sema/address_spaces.c
===================================================================
--- test/Sema/address_spaces.c
+++ test/Sema/address_spaces.c
@@ -71,5 +71,5 @@
// Clang extension doesn't forbid operations on pointers to different address spaces.
char* cmp(_AS1 char *x, _AS2 char *y) {
- return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *') which are pointers to non-overlapping address spaces}}
+ return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
}
Index: test/Sema/address_space_print_macro.c
===================================================================
--- /dev/null
+++ test/Sema/address_space_print_macro.c
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+#define AS1 __attribute__((address_space(1)))
+#define AS2 __attribute__((address_space(2), annotate("foo")))
+
+#define AS(i) address_space(i)
+#define AS3 __attribute__((AS(3)))
+
+#define ATTR __attribute__
+#define AS4 ATTR((AS(4)))
+#define AS5 __attribute__((address_space(5))) char
+
+char *cmp(AS1 char *x, AS2 char *y) {
+ return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
+}
+
+__attribute__((address_space(1))) char test_array[10];
+void test3(void) {
+ extern void test3_helper(char *p); // expected-note{{passing argument to parameter 'p' here}}
+ test3_helper(test_array); // expected-error{{passing '__attribute__((address_space(1))) char *' to parameter of type 'char *' changes address space of pointer}}
+}
+
+char AS2 *test4_array;
+void test4(void) {
+ extern void test3_helper(char *p); // expected-note{{passing argument to parameter 'p' here}}
+ test3_helper(test4_array); // expected-error{{passing 'AS2 char *' to parameter of type 'char *' changes address space of pointer}}
+}
+
+void func() {
+ char AS1 *x;
+ char AS3 *x2;
+ AS4 char *x3;
+ AS5 *x4;
+ char *y;
+ y = x; // expected-error{{assigning 'AS1 char *' to 'char *' changes address space of pointer}}
+ y = x2; // expected-error{{assigning 'AS3 char *' to 'char *' changes address space of pointer}}
+ y = x3; // expected-error{{assigning 'AS4 char *' to 'char *' changes address space of pointer}}
+ y = x4; // expected-error{{assigning '__attribute__((address_space(5))) char *' to 'char *' changes address space of pointer}}
+}
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -404,6 +404,7 @@
Record.AddTypeRef(T->getModifiedType());
Record.AddTypeRef(T->getEquivalentType());
Record.push_back(T->getAttrKind());
+ Record.AddIdentifierRef(T->getMacroIdentifier());
Code = TYPE_ATTRIBUTED;
}
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6168,14 +6168,16 @@
}
case TYPE_ATTRIBUTED: {
- if (Record.size() != 3) {
+ if (Record.size() != 4) {
Error("incorrect encoding of attributed type");
return QualType();
}
QualType modifiedType = readType(*Loc.F, Record, Idx);
QualType equivalentType = readType(*Loc.F, Record, Idx);
AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);
- return Context.getAttributedType(kind, modifiedType, equivalentType);
+ IdentifierInfo *MacroII = GetIdentifierInfo(*Loc.F, Record, Idx);
+ return Context.getAttributedType(kind, modifiedType, equivalentType,
+ MacroII);
}
case TYPE_PAREN: {
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -6087,9 +6087,9 @@
}
}
- result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
- modifiedType,
- equivalentType);
+ result = SemaRef.Context.getAttributedType(TL.getAttrKind(), modifiedType,
+ equivalentType,
+ oldType->getMacroIdentifier());
}
AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -243,9 +243,9 @@
/// Get an attributed type for the given attribute, and remember the Attr
/// object so that we can attach it to the AttributedTypeLoc.
QualType getAttributedType(Attr *A, QualType ModifiedType,
- QualType EquivType) {
- QualType T =
- sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType);
+ QualType EquivType, IdentifierInfo *MacroII) {
+ QualType T = sema.Context.getAttributedType(A->getKind(), ModifiedType,
+ EquivType, MacroII);
AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
AttrsForTypesSorted = false;
return T;
@@ -4258,7 +4258,8 @@
D.getDeclSpec().getEndLoc(),
D.getMutableDeclSpec().getAttributes())) {
T = state.getAttributedType(
- createNullabilityAttr(Context, *attr, *inferNullability), T, T);
+ createNullabilityAttr(Context, *attr, *inferNullability), T, T,
+ attr->getMacroIdentifier());
}
}
}
@@ -5817,7 +5818,7 @@
auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
static_cast<unsigned>(T.getQualifiers().getAddressSpace()));
- Type = State.getAttributedType(ASAttr, T, T);
+ Type = State.getAttributedType(ASAttr, T, T, Attr.getMacroIdentifier());
} else {
Attr.setInvalid();
}
@@ -6012,8 +6013,8 @@
if (!S.getLangOpts().ObjCAutoRefCount &&
lifetime == Qualifiers::OCL_ExplicitNone) {
type = state.getAttributedType(
- createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr),
- type, type);
+ createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr), type,
+ type, attr.getMacroIdentifier());
return true;
}
@@ -6027,7 +6028,7 @@
type = state.getAttributedType(::new (S.Context) ObjCOwnershipAttr(
attr.getRange(), S.Context, II,
attr.getAttributeSpellingListIndex()),
- origType, type);
+ origType, type, attr.getMacroIdentifier());
}
auto diagnoseOrDelay = [](Sema &S, SourceLocation loc,
@@ -6131,7 +6132,7 @@
type = state.getAttributedType(
::new (S.Context) ObjCGCAttr(attr.getRange(), S.Context, II,
attr.getAttributeSpellingListIndex()),
- origType, type);
+ origType, type, attr.getMacroIdentifier());
return true;
}
@@ -6341,7 +6342,7 @@
return true;
}
- Type = State.getAttributedType(A, Type, Type);
+ Type = State.getAttributedType(A, Type, Type, PAttr.getMacroIdentifier());
return false;
}
@@ -6473,7 +6474,8 @@
// Form the attributed type.
type = state.getAttributedType(
- createNullabilityAttr(S.Context, attr, nullability), type, type);
+ createNullabilityAttr(S.Context, attr, nullability), type, type,
+ attr.getMacroIdentifier());
return false;
}
@@ -6486,7 +6488,8 @@
if (isa<ObjCTypeParamType>(type)) {
// Build the attributed type to record where __kindof occurred.
type = state.getAttributedType(
- createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, type);
+ createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, type,
+ attr.getMacroIdentifier());
return false;
}
@@ -6521,13 +6524,15 @@
"multiple spellings for __kindof?");
Attr *A = createNullabilityAttr(S.Context, attr, *nullability);
A->setImplicit(true);
- equivType = state.getAttributedType(A, equivType, equivType);
+ equivType = state.getAttributedType(A, equivType, equivType,
+ attr.getMacroIdentifier());
}
}
// Build the attributed type to record where __kindof occurred.
- type = state.getAttributedType(
- createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, equivType);
+ type =
+ state.getAttributedType(createSimpleAttr<ObjCKindOfAttr>(S.Context, attr),
+ type, equivType, attr.getMacroIdentifier());
return false;
}
@@ -6712,8 +6717,8 @@
type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
}
type = state.getAttributedType(
- createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr),
- origType, type);
+ createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr), origType,
+ type, attr.getMacroIdentifier());
return true;
}
@@ -6847,7 +6852,8 @@
Equivalent =
unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
}
- type = state.getAttributedType(CCAttr, type, Equivalent);
+ type = state.getAttributedType(CCAttr, type, Equivalent,
+ attr.getMacroIdentifier());
return true;
}
@@ -7209,7 +7215,7 @@
if (State.getDeclarator().isDeclarationOfFunction()) {
CurType = State.getAttributedType(
createSimpleAttr<LifetimeBoundAttr>(State.getSema().Context, Attr),
- CurType, CurType);
+ CurType, CurType, Attr.getMacroIdentifier());
} else {
Attr.diagnoseAppertainsTo(State.getSema(), nullptr);
}
Index: lib/Sema/SemaObjCProperty.cpp
===================================================================
--- lib/Sema/SemaObjCProperty.cpp
+++ lib/Sema/SemaObjCProperty.cpp
@@ -2384,8 +2384,9 @@
QualType modifiedTy = resultTy;
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
if (*nullability == NullabilityKind::Unspecified)
- resultTy = Context.getAttributedType(attr::TypeNonNull,
- modifiedTy, modifiedTy);
+ resultTy = Context.getAttributedType(
+ attr::TypeNonNull, modifiedTy, modifiedTy,
+ resultTy->getAs<AttributedType>()->getMacroIdentifier());
}
}
@@ -2458,8 +2459,9 @@
QualType modifiedTy = paramTy;
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
if (*nullability == NullabilityKind::Unspecified)
- paramTy = Context.getAttributedType(attr::TypeNullable,
- modifiedTy, modifiedTy);
+ paramTy = Context.getAttributedType(
+ attr::TypeNullable, modifiedTy, modifiedTy,
+ paramTy->getAs<AttributedType>()->getMacroIdentifier());
}
}
Index: lib/Sema/SemaExprObjC.cpp
===================================================================
--- lib/Sema/SemaExprObjC.cpp
+++ lib/Sema/SemaExprObjC.cpp
@@ -569,7 +569,10 @@
if (Nullability)
BoxedType = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
- BoxedType);
+ BoxedType,
+ BoxingMethod->getReturnType()
+ ->getAs<AttributedType>()
+ ->getMacroIdentifier());
}
} else if (ValueType->isBuiltinType()) {
// The other types we support are numeric, char and BOOL/bool. We could also
@@ -1262,9 +1265,9 @@
if (auto nullability = AttributedType::stripOuterNullability(T)) {
if (T == Context.getObjCInstanceType()) {
return Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(*nullability),
- Context.getObjCIdType(),
- Context.getObjCIdType());
+ AttributedType::getNullabilityAttrKind(*nullability),
+ Context.getObjCIdType(), Context.getObjCIdType(),
+ origType->getAs<AttributedType>()->getMacroIdentifier());
}
return origType;
@@ -1296,16 +1299,15 @@
// result type to the returned result.
auto transferNullability = [&](QualType type) -> QualType {
// If the method's result type has nullability, extract it.
- if (auto nullability = Method->getSendResultType(ReceiverType)
- ->getNullability(Context)){
+ QualType MethodResultTy = Method->getSendResultType(ReceiverType);
+ if (auto nullability = MethodResultTy->getNullability(Context)) {
// Strip off any outer nullability sugar from the provided type.
(void)AttributedType::stripOuterNullability(type);
// Form a new attributed type using the method result type's nullability.
return Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(*nullability),
- type,
- type);
+ AttributedType::getNullabilityAttrKind(*nullability), type, type,
+ MethodResultTy->getAs<AttributedType>()->getMacroIdentifier());
}
return type;
@@ -1408,8 +1410,8 @@
auto newNullability
= static_cast<NullabilityKind>(newResultNullabilityIdx-1);
return Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(newNullability),
- resultType, resultType);
+ AttributedType::getNullabilityAttrKind(newNullability), resultType,
+ resultType, nullptr);
}
return resultType;
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -7266,7 +7266,7 @@
// Create a new AttributedType with the new nullability kind.
auto NewAttr = AttributedType::getNullabilityAttrKind(MergedKind);
- return Ctx.getAttributedType(NewAttr, ResTy, ResTy);
+ return Ctx.getAttributedType(NewAttr, ResTy, ResTy, nullptr);
}
/// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
Index: lib/Sema/SemaDeclObjC.cpp
===================================================================
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -4428,8 +4428,8 @@
// Otherwise, provide the result with the same nullability.
return S.Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(*prevNullability),
- type, type);
+ AttributedType::getNullabilityAttrKind(*prevNullability), type, type,
+ nullptr);
}
/// Merge information from the declaration of a method in the \@interface
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2784,8 +2784,8 @@
} else {
QualType NewT = NewParam->getType();
NewT = S.Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(*Oldnullability),
- NewT, NewT);
+ AttributedType::getNullabilityAttrKind(*Oldnullability), NewT, NewT,
+ OldParam->getType()->getAs<AttributedType>()->getMacroIdentifier());
NewParam->setType(NewT);
}
}
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -135,6 +135,10 @@
assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
while (Tok.is(tok::kw___attribute)) {
+ Token AttrTok = Tok;
+ unsigned OldNumAttrs = attrs.size();
+ unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
+
ConsumeToken();
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"attribute")) {
@@ -203,6 +207,35 @@
SkipUntil(tok::r_paren, StopAtSemi);
if (endLoc)
*endLoc = Loc;
+
+ // If this was declared in a macro, attatch the macro IdentifierInfo to the
+ // parsed attribute.
+ SourceLocation AttrTokLoc = AttrTok.getLocation();
+ auto &SrcMgr = PP.getSourceManager();
+ bool AttrStartIsInMacro =
+ (AttrTokLoc.isMacroID() && Lexer::isAtStartOfMacroExpansion(
+ AttrTokLoc, SrcMgr, PP.getLangOpts()));
+ bool AttrEndIsInMacro =
+ (Loc.isMacroID() &&
+ Lexer::isAtEndOfMacroExpansion(Loc, SrcMgr, PP.getLangOpts()));
+ bool WholeAttrIsInMacro =
+ (AttrStartIsInMacro && AttrEndIsInMacro &&
+ SrcMgr.getExpansionLoc(AttrTokLoc) == SrcMgr.getExpansionLoc(Loc));
+
+ if (WholeAttrIsInMacro) {
+ StringRef name = Lexer::getSourceText(
+ SrcMgr.getExpansionRange(AttrTokLoc), SrcMgr, PP.getLangOpts());
+ IdentifierInfo *MacroII = PP.getIdentifierInfo(name);
+
+ for (unsigned i = OldNumAttrs; i < attrs.size(); ++i)
+ attrs[i].setMacroIdentifier(MacroII);
+
+ if (LateAttrs) {
+ for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i) {
+ (*LateAttrs)[i]->MacroII = MacroII;
+ }
+ }
+ }
}
}
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp
+++ lib/AST/TypePrinter.cpp
@@ -1364,7 +1364,18 @@
if (T->getAttrKind() == attr::ObjCKindOf)
OS << "__kindof ";
- printBefore(T->getModifiedType(), OS);
+ if (T->getAttrKind() == attr::AddressSpace && T->hasMacroIdentifier()) {
+ OS << T->getMacroIdentifier()->getName() << " ";
+
+ // Remove the underlying address_space so it won't be printed.
+ SplitQualType SplitTy = T->getModifiedType().split();
+ Qualifiers Quals = SplitTy.Quals;
+ if (Quals.getAddressSpace() >= LangAS::FirstTargetAddressSpace)
+ Quals.removeAddressSpace();
+ printBefore(SplitTy.Ty, Quals, OS);
+ } else {
+ printBefore(T->getModifiedType(), OS);
+ }
if (T->isMSTypeSpec()) {
switch (T->getAttrKind()) {
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -1004,8 +1004,8 @@
== T->getEquivalentType().getAsOpaquePtr())
return QualType(T, 0);
- return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
- equivalentType);
+ return Ctx.getAttributedType(T->getAttrKind(), modifiedType, equivalentType,
+ T->getMacroIdentifier());
}
QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -986,8 +986,9 @@
return {};
}
- return Importer.getToContext().getAttributedType(T->getAttrKind(),
- ToModifiedType, ToEquivalentType);
+ return Importer.getToContext().getAttributedType(
+ T->getAttrKind(), ToModifiedType, ToEquivalentType,
+ T->getMacroIdentifier());
}
QualType ASTNodeImporter::VisitTemplateTypeParmType(
Index: lib/AST/ASTDiagnostic.cpp
===================================================================
--- lib/AST/ASTDiagnostic.cpp
+++ lib/AST/ASTDiagnostic.cpp
@@ -74,19 +74,22 @@
QualType RT = Desugar(Context, SugarRT, DesugarReturn);
if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
RT = Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
+ AttributedType::getNullabilityAttrKind(*nullability), RT, RT,
+ FT->getReturnType()->getAs<AttributedType>()->getMacroIdentifier());
}
bool DesugarArgument = false;
SmallVector<QualType, 4> Args;
const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
if (FPT) {
for (QualType SugarPT : FPT->param_types()) {
QualType PT = Desugar(Context, SugarPT, DesugarArgument);
+ QualType OldSugarPT = SugarPT;
if (auto nullability =
AttributedType::stripOuterNullability(SugarPT)) {
PT = Context.getAttributedType(
- AttributedType::getNullabilityAttrKind(*nullability), PT, PT);
+ AttributedType::getNullabilityAttrKind(*nullability), PT, PT,
+ OldSugarPT->getAs<AttributedType>()->getMacroIdentifier());
}
Args.push_back(PT);
}
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -2708,7 +2708,8 @@
return getAttributedType(
AT->getAttrKind(),
getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
- getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
+ getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI),
+ AT->getMacroIdentifier());
// Anything else must be a function type. Rebuild it with the new exception
// specification.
@@ -3878,17 +3879,18 @@
QualType ASTContext::getAttributedType(attr::Kind attrKind,
QualType modifiedType,
- QualType equivalentType) {
+ QualType equivalentType,
+ const IdentifierInfo *MacroII) {
llvm::FoldingSetNodeID id;
- AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
+ AttributedType::Profile(id, attrKind, modifiedType, equivalentType, MacroII);
void *insertPos = nullptr;
AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
if (type) return QualType(type, 0);
QualType canon = getCanonicalType(equivalentType);
type = new (*this, TypeAlignment)
- AttributedType(canon, attrKind, modifiedType, equivalentType);
+ AttributedType(canon, attrKind, modifiedType, equivalentType, MacroII);
Types.push_back(type);
AttributedTypes.InsertNode(type, insertPos);
@@ -5461,7 +5463,8 @@
// int x[_Nullable] -> int * _Nullable
if (auto Nullability = Ty->getNullability(*this)) {
Result = const_cast<ASTContext *>(this)->getAttributedType(
- AttributedType::getNullabilityAttrKind(*Nullability), Result, Result);
+ AttributedType::getNullabilityAttrKind(*Nullability), Result, Result,
+ Ty->getAs<AttributedType>()->getMacroIdentifier());
}
return Result;
}
Index: include/clang/Sema/ParsedAttr.h
===================================================================
--- include/clang/Sema/ParsedAttr.h
+++ include/clang/Sema/ParsedAttr.h
@@ -168,6 +168,7 @@
private:
IdentifierInfo *AttrName;
IdentifierInfo *ScopeName;
+ IdentifierInfo *MacroII = nullptr;
SourceRange AttrRange;
SourceLocation ScopeLoc;
SourceLocation EllipsisLoc;
@@ -534,6 +535,17 @@
return getPropertyDataBuffer().SetterId;
}
+ /// Set the macro identifier info object that this parsed attribute was
+ /// declared in if it was declared in a macro.
+ void setMacroIdentifier(IdentifierInfo *MacroName) { MacroII = MacroName; }
+
+ /// Returns true if this attribute was declared in a macro.
+ bool hasMacroIdentifier() const { return MacroII != nullptr; }
+
+ /// Return the macro identifier if this attribute was declared in a macro.
+ /// nullptr is returned if it was not declared in a macro.
+ IdentifierInfo *getMacroIdentifier() const { return MacroII; }
+
/// Get an index into the attribute spelling list
/// defined in Attr.td. This index is used by an attribute
/// to pretty print itself.
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h
+++ include/clang/Parse/Parser.h
@@ -1114,6 +1114,7 @@
Parser *Self;
CachedTokens Toks;
IdentifierInfo &AttrName;
+ IdentifierInfo *MacroII = nullptr;
SourceLocation AttrNameLoc;
SmallVector<Decl*, 2> Decls;
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -4315,13 +4315,18 @@
QualType ModifiedType;
QualType EquivalentType;
+ // If the attribute this type holds was declared entirely in a macro, we store
+ // the macro identifier information. This can be used for printing the macro
+ // name instead of the attribute.
+ const IdentifierInfo *MacroII;
+
AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
- QualType equivalent)
+ QualType equivalent, const IdentifierInfo *macroII)
: Type(Attributed, canon, equivalent->isDependentType(),
equivalent->isInstantiationDependentType(),
equivalent->isVariablyModifiedType(),
equivalent->containsUnexpandedParameterPack()),
- ModifiedType(modified), EquivalentType(equivalent) {
+ ModifiedType(modified), EquivalentType(equivalent), MacroII(macroII) {
AttributedTypeBits.AttrKind = attrKind;
}
@@ -4333,6 +4338,11 @@
QualType getModifiedType() const { return ModifiedType; }
QualType getEquivalentType() const { return EquivalentType; }
+ /// Retrieve the type macro identifier info object that this type was created
+ /// with (if available).
+ const IdentifierInfo *getMacroIdentifier() const { return MacroII; }
+ bool hasMacroIdentifier() const { return MacroII != nullptr; }
+
bool isSugared() const { return true; }
QualType desugar() const { return getEquivalentType(); }
@@ -4387,14 +4397,16 @@
static Optional<NullabilityKind> stripOuterNullability(QualType &T);
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
+ Profile(ID, getAttrKind(), ModifiedType, EquivalentType, MacroII);
}
static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
- QualType modified, QualType equivalent) {
+ QualType modified, QualType equivalent,
+ const IdentifierInfo *macroII) {
ID.AddInteger(attrKind);
ID.AddPointer(modified.getAsOpaquePtr());
ID.AddPointer(equivalent.getAsOpaquePtr());
+ ID.AddPointer(macroII);
}
static bool classof(const Type *T) {
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1423,9 +1423,9 @@
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
- QualType getAttributedType(attr::Kind attrKind,
- QualType modifiedType,
- QualType equivalentType);
+ QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
+ QualType equivalentType,
+ const IdentifierInfo *MacroII);
QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
QualType Replacement) const;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits