Skip to content

Commit fc40cbd

Browse files
committed
[Attribute/Diagnostics] Print macro if definition is an attribute declaration
If an address_space attribute is defined in a macro, print the macro instead when diagnosing a warning or error for incompatible pointers with different address_spaces. We allow this for all attributes (not just address_space), and for multiple attributes declared in the same macro. Differential Revision: https://reviews.llvm.org/D51329 llvm-svn: 359826
1 parent 206bc17 commit fc40cbd

33 files changed

+407
-20
lines changed

clang/include/clang/AST/ASTContext.h

+3
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
14411441

14421442
QualType getParenType(QualType NamedType) const;
14431443

1444+
QualType getMacroQualifiedType(QualType UnderlyingTy,
1445+
const IdentifierInfo *MacroII) const;
1446+
14441447
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
14451448
NestedNameSpecifier *NNS, QualType NamedType,
14461449
TagDecl *OwnedTagDecl = nullptr) const;

clang/include/clang/AST/RecursiveASTVisitor.h

+6
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,9 @@ DEF_TRAVERSE_TYPE(AttributedType,
10651065

10661066
DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
10671067

1068+
DEF_TRAVERSE_TYPE(MacroQualifiedType,
1069+
{ TRY_TO(TraverseType(T->getUnderlyingType())); })
1070+
10681071
DEF_TRAVERSE_TYPE(ElaboratedType, {
10691072
if (T->getQualifier()) {
10701073
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
@@ -1308,6 +1311,9 @@ DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
13081311

13091312
DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
13101313

1314+
DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
1315+
{ TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1316+
13111317
DEF_TRAVERSE_TYPELOC(AttributedType,
13121318
{ TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
13131319

clang/include/clang/AST/Type.h

+37
Original file line numberDiff line numberDiff line change
@@ -4184,6 +4184,41 @@ class TypedefType : public Type {
41844184
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
41854185
};
41864186

4187+
/// Sugar type that represents a type that was qualified by a qualifier written
4188+
/// as a macro invocation.
4189+
class MacroQualifiedType : public Type {
4190+
friend class ASTContext; // ASTContext creates these.
4191+
4192+
QualType UnderlyingTy;
4193+
const IdentifierInfo *MacroII;
4194+
4195+
MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy,
4196+
const IdentifierInfo *MacroII)
4197+
: Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(),
4198+
UnderlyingTy->isInstantiationDependentType(),
4199+
UnderlyingTy->isVariablyModifiedType(),
4200+
UnderlyingTy->containsUnexpandedParameterPack()),
4201+
UnderlyingTy(UnderlyingTy), MacroII(MacroII) {
4202+
assert(isa<AttributedType>(UnderlyingTy) &&
4203+
"Expected a macro qualified type to only wrap attributed types.");
4204+
}
4205+
4206+
public:
4207+
const IdentifierInfo *getMacroIdentifier() const { return MacroII; }
4208+
QualType getUnderlyingType() const { return UnderlyingTy; }
4209+
4210+
/// Return this attributed type's modified type with no qualifiers attached to
4211+
/// it.
4212+
QualType getModifiedType() const;
4213+
4214+
bool isSugared() const { return true; }
4215+
QualType desugar() const;
4216+
4217+
static bool classof(const Type *T) {
4218+
return T->getTypeClass() == MacroQualified;
4219+
}
4220+
};
4221+
41874222
/// Represents a `typeof` (or __typeof__) expression (a GCC extension).
41884223
class TypeOfExprType : public Type {
41894224
Expr *TOExpr;
@@ -6805,6 +6840,8 @@ template <typename T> const T *Type::getAsAdjusted() const {
68056840
Ty = P->desugar().getTypePtr();
68066841
else if (const auto *A = dyn_cast<AdjustedType>(Ty))
68076842
Ty = A->desugar().getTypePtr();
6843+
else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty))
6844+
Ty = M->desugar().getTypePtr();
68086845
else
68096846
break;
68106847
}

clang/include/clang/AST/TypeLoc.h

+38
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ class TypeLoc {
173173

174174
TypeLoc IgnoreParens() const;
175175

176+
/// Strips MacroDefinitionTypeLocs from a type location.
177+
TypeLoc IgnoreMacroDefinitions() const;
178+
176179
/// Find a type with the location of an explicit type qualifier.
177180
///
178181
/// The result, if non-null, will be one of:
@@ -1080,6 +1083,39 @@ class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
10801083
}
10811084
};
10821085

1086+
struct MacroQualifiedLocInfo {
1087+
SourceLocation ExpansionLoc;
1088+
};
1089+
1090+
class MacroQualifiedTypeLoc
1091+
: public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
1092+
MacroQualifiedType, MacroQualifiedLocInfo> {
1093+
public:
1094+
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1095+
setExpansionLoc(Loc);
1096+
}
1097+
1098+
TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1099+
1100+
const IdentifierInfo *getMacroIdentifier() const {
1101+
return getTypePtr()->getMacroIdentifier();
1102+
}
1103+
1104+
SourceLocation getExpansionLoc() const {
1105+
return this->getLocalData()->ExpansionLoc;
1106+
}
1107+
1108+
void setExpansionLoc(SourceLocation Loc) {
1109+
this->getLocalData()->ExpansionLoc = Loc;
1110+
}
1111+
1112+
QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); }
1113+
1114+
SourceRange getLocalSourceRange() const {
1115+
return getInnerLoc().getLocalSourceRange();
1116+
}
1117+
};
1118+
10831119
struct ParenLocInfo {
10841120
SourceLocation LParenLoc;
10851121
SourceLocation RParenLoc;
@@ -2289,6 +2325,8 @@ inline T TypeLoc::getAsAdjusted() const {
22892325
Cur = ETL.getNamedTypeLoc();
22902326
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
22912327
Cur = ATL.getOriginalLoc();
2328+
else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2329+
Cur = MQL.getInnerLoc();
22922330
else
22932331
break;
22942332
}

clang/include/clang/AST/TypeNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ TYPE(FunctionNoProto, FunctionType)
8282
DEPENDENT_TYPE(UnresolvedUsing, Type)
8383
NON_CANONICAL_TYPE(Paren, Type)
8484
NON_CANONICAL_TYPE(Typedef, Type)
85+
NON_CANONICAL_TYPE(MacroQualified, Type)
8586
NON_CANONICAL_TYPE(Adjusted, Type)
8687
NON_CANONICAL_TYPE(Decayed, AdjustedType)
8788
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)

clang/include/clang/Parse/Parser.h

+1
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,7 @@ class Parser : public CodeCompletionHandler {
11521152
Parser *Self;
11531153
CachedTokens Toks;
11541154
IdentifierInfo &AttrName;
1155+
IdentifierInfo *MacroII = nullptr;
11551156
SourceLocation AttrNameLoc;
11561157
SmallVector<Decl*, 2> Decls;
11571158

clang/include/clang/Sema/ParsedAttr.h

+23
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class ParsedAttr final
167167
private:
168168
IdentifierInfo *AttrName;
169169
IdentifierInfo *ScopeName;
170+
IdentifierInfo *MacroII = nullptr;
171+
SourceLocation MacroExpansionLoc;
170172
SourceRange AttrRange;
171173
SourceLocation ScopeLoc;
172174
SourceLocation EllipsisLoc;
@@ -547,6 +549,27 @@ class ParsedAttr final
547549
return getPropertyDataBuffer().SetterId;
548550
}
549551

552+
/// Set the macro identifier info object that this parsed attribute was
553+
/// declared in if it was declared in a macro. Also set the expansion location
554+
/// of the macro.
555+
void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) {
556+
MacroII = MacroName;
557+
MacroExpansionLoc = Loc;
558+
}
559+
560+
/// Returns true if this attribute was declared in a macro.
561+
bool hasMacroIdentifier() const { return MacroII != nullptr; }
562+
563+
/// Return the macro identifier if this attribute was declared in a macro.
564+
/// nullptr is returned if it was not declared in a macro.
565+
IdentifierInfo *getMacroIdentifier() const { return MacroII; }
566+
567+
SourceLocation getMacroExpansionLoc() const {
568+
assert(hasMacroIdentifier() && "Can only get the macro expansion location "
569+
"if this attribute has a macro identifier.");
570+
return MacroExpansionLoc;
571+
}
572+
550573
/// Get an index into the attribute spelling list
551574
/// defined in Attr.td. This index is used by an attribute
552575
/// to pretty print itself.

clang/include/clang/Sema/Sema.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3516,7 +3516,7 @@ class Sema {
35163516
// Check if there is an explicit attribute, but only look through parens.
35173517
// The intent is to look for an attribute on the current declarator, but not
35183518
// one that came from a typedef.
3519-
bool hasExplicitCallingConv(QualType &T);
3519+
bool hasExplicitCallingConv(QualType T);
35203520

35213521
/// Get the outermost AttributedType node that sets a calling convention.
35223522
/// Valid types should not have multiple attributes with different CCs.

clang/include/clang/Serialization/ASTBitCodes.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,10 @@ namespace serialization {
11731173
TYPE_DEPENDENT_ADDRESS_SPACE = 47,
11741174

11751175
/// A dependentSizedVectorType record.
1176-
TYPE_DEPENDENT_SIZED_VECTOR = 48
1176+
TYPE_DEPENDENT_SIZED_VECTOR = 48,
1177+
1178+
/// A type defined in a macro.
1179+
TYPE_MACRO_QUALIFIED = 49
11771180
};
11781181

11791182
/// The type IDs for special types constructed by semantic

clang/lib/ARCMigrate/TransGCAttrs.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class GCAttrsCollector : public RecursiveASTVisitor<GCAttrsCollector> {
6868
if (handleAttr(Attr, D))
6969
break;
7070
TL = Attr.getModifiedLoc();
71+
} else if (MacroQualifiedTypeLoc MDTL =
72+
TL.getAs<MacroQualifiedTypeLoc>()) {
73+
TL = MDTL.getInnerLoc();
7174
} else if (ArrayTypeLoc Arr = TL.getAs<ArrayTypeLoc>()) {
7275
TL = Arr.getElementLoc();
7376
} else if (PointerTypeLoc PT = TL.getAs<PointerTypeLoc>()) {

clang/lib/AST/ASTContext.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
20472047
case Type::Paren:
20482048
return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
20492049

2050+
case Type::MacroQualified:
2051+
return getTypeInfo(
2052+
cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr());
2053+
20502054
case Type::ObjCTypeParam:
20512055
return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
20522056

@@ -3929,7 +3933,7 @@ QualType ASTContext::getAttributedType(attr::Kind attrKind,
39293933

39303934
QualType canon = getCanonicalType(equivalentType);
39313935
type = new (*this, TypeAlignment)
3932-
AttributedType(canon, attrKind, modifiedType, equivalentType);
3936+
AttributedType(canon, attrKind, modifiedType, equivalentType);
39333937

39343938
Types.push_back(type);
39353939
AttributedTypes.InsertNode(type, insertPos);
@@ -4210,6 +4214,19 @@ ASTContext::getParenType(QualType InnerType) const {
42104214
return QualType(T, 0);
42114215
}
42124216

4217+
QualType
4218+
ASTContext::getMacroQualifiedType(QualType UnderlyingTy,
4219+
const IdentifierInfo *MacroII) const {
4220+
QualType Canon = UnderlyingTy;
4221+
if (!Canon.isCanonical())
4222+
Canon = getCanonicalType(UnderlyingTy);
4223+
4224+
auto *newType = new (*this, TypeAlignment)
4225+
MacroQualifiedType(UnderlyingTy, Canon, MacroII);
4226+
Types.push_back(newType);
4227+
return QualType(newType, 0);
4228+
}
4229+
42134230
QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
42144231
NestedNameSpecifier *NNS,
42154232
const IdentifierInfo *Name,

clang/lib/AST/ASTDiagnostic.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
4141
QT = PT->desugar();
4242
continue;
4343
}
44+
// ... or a macro defined type ...
45+
if (const MacroQualifiedType *MDT = dyn_cast<MacroQualifiedType>(Ty)) {
46+
QT = MDT->desugar();
47+
continue;
48+
}
4449
// ...or a substituted template type parameter ...
4550
if (const SubstTemplateTypeParmType *ST =
4651
dyn_cast<SubstTemplateTypeParmType>(Ty)) {

clang/lib/AST/ASTStructuralEquivalence.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
595595
return false;
596596
break;
597597

598+
case Type::MacroQualified:
599+
if (!IsStructurallyEquivalent(
600+
Context, cast<MacroQualifiedType>(T1)->getUnderlyingType(),
601+
cast<MacroQualifiedType>(T2)->getUnderlyingType()))
602+
return false;
603+
break;
604+
598605
case Type::Typedef:
599606
if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
600607
cast<TypedefType>(T2)->getDecl()))

clang/lib/AST/ItaniumMangle.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
19411941
case Type::ObjCTypeParam:
19421942
case Type::Atomic:
19431943
case Type::Pipe:
1944+
case Type::MacroQualified:
19441945
llvm_unreachable("type is illegal as a nested name specifier");
19451946

19461947
case Type::SubstTemplateTypeParmPack:

clang/lib/AST/Type.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
973973

974974
SUGARED_TYPE_CLASS(Typedef)
975975
SUGARED_TYPE_CLASS(ObjCTypeParam)
976+
SUGARED_TYPE_CLASS(MacroQualified)
976977

977978
QualType VisitAdjustedType(const AdjustedType *T) {
978979
QualType originalType = recurse(T->getOriginalType());
@@ -1735,6 +1736,10 @@ namespace {
17351736
return Visit(T->getModifiedType());
17361737
}
17371738

1739+
Type *VisitMacroQualifiedType(const MacroQualifiedType *T) {
1740+
return Visit(T->getUnderlyingType());
1741+
}
1742+
17381743
Type *VisitAdjustedType(const AdjustedType *T) {
17391744
return Visit(T->getOriginalType());
17401745
}
@@ -3160,6 +3165,20 @@ QualType TypedefType::desugar() const {
31603165
return getDecl()->getUnderlyingType();
31613166
}
31623167

3168+
QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); }
3169+
3170+
QualType MacroQualifiedType::getModifiedType() const {
3171+
// Step over MacroQualifiedTypes from the same macro to find the type
3172+
// ultimately qualified by the macro qualifier.
3173+
QualType Inner = cast<AttributedType>(getUnderlyingType())->getModifiedType();
3174+
while (auto *InnerMQT = dyn_cast<MacroQualifiedType>(Inner)) {
3175+
if (InnerMQT->getMacroIdentifier() != getMacroIdentifier())
3176+
break;
3177+
Inner = InnerMQT->getModifiedType();
3178+
}
3179+
return Inner;
3180+
}
3181+
31633182
TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
31643183
: Type(TypeOfExpr, can, E->isTypeDependent(),
31653184
E->isInstantiationDependent(),

clang/lib/AST/TypePrinter.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
259259
case Type::Paren:
260260
case Type::PackExpansion:
261261
case Type::SubstTemplateTypeParm:
262+
case Type::MacroQualified:
262263
CanPrefixQualifiers = false;
263264
break;
264265

@@ -963,6 +964,21 @@ void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
963964
printTypeSpec(T->getDecl(), OS);
964965
}
965966

967+
void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
968+
raw_ostream &OS) {
969+
StringRef MacroName = T->getMacroIdentifier()->getName();
970+
OS << MacroName << " ";
971+
972+
// Since this type is meant to print the macro instead of the whole attribute,
973+
// we trim any attributes and go directly to the original modified type.
974+
printBefore(T->getModifiedType(), OS);
975+
}
976+
977+
void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
978+
raw_ostream &OS) {
979+
printAfter(T->getModifiedType(), OS);
980+
}
981+
966982
void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
967983

968984
void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,

clang/lib/CodeGen/CGDebugInfo.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,9 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
28442844
case Type::Paren:
28452845
T = cast<ParenType>(T)->getInnerType();
28462846
break;
2847+
case Type::MacroQualified:
2848+
T = cast<MacroQualifiedType>(T)->getUnderlyingType();
2849+
break;
28472850
case Type::SubstTemplateTypeParm:
28482851
T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
28492852
break;
@@ -3023,6 +3026,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
30233026
case Type::DeducedTemplateSpecialization:
30243027
case Type::Elaborated:
30253028
case Type::Paren:
3029+
case Type::MacroQualified:
30263030
case Type::SubstTemplateTypeParm:
30273031
case Type::TypeOfExpr:
30283032
case Type::TypeOf:

clang/lib/CodeGen/CodeGenFunction.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
21492149
case Type::Attributed:
21502150
case Type::SubstTemplateTypeParm:
21512151
case Type::PackExpansion:
2152+
case Type::MacroQualified:
21522153
// Keep walking after single level desugaring.
21532154
type = type.getSingleStepDesugaredType(getContext());
21542155
break;

0 commit comments

Comments
 (0)